问题
I have 2000 TEI-XML-files with letters between different people and a single person in a single folder. I can access the previous and next letter chronologically as the filename starts with the date of the sender (e.g. 2001-02-21.xml). But what I want to achieve is to create an XSLT (2 or 3, doesn't matter) that writes the next letter to or from the specific writer/receiver into the xml-file.
Say I have this:
<correspDesc>
<correspAction type="sent">
<persName key="CMvW">Carl Maria von Weber</persName>
<settlement>Dresden</settlement>
<date when="1817-06-23">23 June 1817</date>
</correspAction>
<correspAction type="received">
<persName key="CB">Caroline Brandt</persName>
<settlement>Prag</settlement>
</correspAction>
</correspDesc>
and i want to add this field as a third child after correspAction:
<correspContext>
<ref type="prev"
target="http://www.weber-gesamtausgabe.de/A041209">Previous letter of
<persName key="CMvW">Carl Maria von Weber</persName>
to <persName key="CB">Caroline Brandt</persName>:
<date from="1817-06-19" to="1817-06-20">June 19/20, 1817</date>
</ref>
<ref type="next"
target="http://www.weber-gesamtausgabe.de/A041217">Next letter of
<persName key="CMvW">Carl Maria von Weber</persName> to
<persName key="CB">Caroline Brandt</persName>:
<date when="1817-06-27">June 27, 1817</date>
</ref>
</correspContext>
how would I do it? In the example Caroline Brandt is the changing sender/receiver. So basically I would need a collection of all XML-files with //correspDesc//persName[@key='CB'] and in each file access the preceding and following one of the collection. How can I achieve that?
begin of the solution
@martin-honnen pointed me the way though I'm certain it is not the most elegant way.
1) I've used collection to copy all correspDesc into one file. I add an attribute 'lookup' with the key of the person and the date the letter was sent combined and an attribute with just 'person' to identify the letters of a correspondence.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="false"/>
<xsl:template match="/">
<xsl:element name="root">
<xsl:for-each select="collection('?select=*.xml;recurse=no')">
<xsl:element name="correspDesc">
<xsl:attribute name="lookup">
<xsl:choose>
<xsl:when test="//correspAction[@type='sent']/persName/@key='pmb2121'">
<xsl:value-of select="//correspAction[@type='received']/persName/@key"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="//correspAction[@type='sent']/date/@when"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//correspAction[@type='sent']/persName/@key"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="//correspAction[@type='sent']/date/@when"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="person">
<xsl:choose>
<xsl:when test="//correspAction[@type='sent']/persName/@key='pmb2121'">
<xsl:value-of select="//correspAction[@type='received']/persName/@key"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//correspAction[@type='sent']/persName/@key"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="//correspAction"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
2) I order the resulting list using the date-field
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:mode on-no-match="shallow-copy" />
<xsl:output indent="yes"
method="xml"
encoding="utf-8"
omit-xml-declaration="false"/>
<xsl:template match="root">
<xsl:element name="root">
<xsl:apply-templates select="correspDesc">
<xsl:sort select="correspAction[@type='sent']/date/@when" data-type="text" order="ascending"/>
</xsl:apply-templates>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Now my next task is to use param and key to lookup the preceding and following entries.
<xsl:param name="correspList" select="document('correspList.xml')"/>
<xsl:key name="corresp-lookup" match="@lookup"/>
<xsl:key name="correspPerson-lookup" match="@person"/>
I am not sure how I will achieve that but I will update here once I have that code.
来源:https://stackoverflow.com/questions/58977093/how-to-access-previous-and-next-item-based-on-a-condition