В https://xsltfiddle.liberty -development.net / pPzifp2 / 7 Я пытался сохранить ваши группы корреспонденции в XPath 3.1 array(xs:string*)
Например, [('anna', 'abraham'), 'bertram', 'charlotte']
означает, что вы хотите обработать три группы корреспонденции,первое с двумя именами anna
и abraham
, второе и третье с одним именем (т.е. bertram
и charlotte
).
Для поиска я использовал ключи для выбора отправителей (<xsl:key name="sent-by" match="TEI" use="correspDesc/correspAction[@type = 'sent']/persName/@key"/>
) и получателей (<xsl:key name="received-by" match="TEI" use="correspDesc/correspAction[@type = 'received']/persName/@key"/>
), а затем, я думаю, вы можете пересечь каждую группу с ключами с противоположной группой с ключами на william
(т.е. пересечь, отправленный, например, "bertram" с полученным "william"):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="persons" as="array(xs:string*)"
select="[('anna', 'abraham'), 'bertram', 'charlotte']"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:key name="sent-by" match="TEI" use="correspDesc/correspAction[@type = 'sent']/persName/@key"/>
<xsl:key name="received-by" match="TEI" use="correspDesc/correspAction[@type = 'received']/persName/@key"/>
<xsl:variable name="sent-by-william" select="key('sent-by', 'william')"/>
<xsl:variable name="received-by-william" select="key('received-by', 'william')"/>
<xsl:template match="/*">
<xsl:variable name="root" select="."/>
<xsl:copy>
<xsl:for-each select="1 to array:size($persons)">
<xsl:apply-templates
select="key('sent-by', $persons(.), $root) intersect $received-by-william |
key('received-by', $persons(.), $root) intersect $sent-by-william">
<xsl:with-param name="correspondence" select="$persons(.)[1]"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="TEI">
<xsl:param name="correspondence"/>
<TEI correspondence="{$correspondence}">
<xsl:apply-templates select="@* | node()"/>
</TEI>
</xsl:template>
</xsl:stylesheet>
Это дает результат (как только я исправил элемент xml:id="7"
, чтобы он имел элемент correspDesc
)
<?xml version="1.0" encoding="UTF-8"?>
<root>
<TEI correspondence="anna" xml:id="1">
<correspDesc>
<correspAction type="sent">
<persName key="william"/>
</correspAction>
<correspAction type="received">
<persName key="anna"/>
</correspAction>
</correspDesc>
<text/>
</TEI>
<TEI correspondence="anna" xml:id="2">
<correspDesc>
<correspAction type="sent">
<persName key="anna"/>
</correspAction>
<correspAction type="received">
<persName key="william"/>
</correspAction>
</correspDesc>
<text/>
</TEI>
<TEI correspondence="anna" xml:id="4">
<correspDesc>
<correspAction type="sent">
<persName key="charlotte"/>
<persName key="anna"/>
</correspAction>
<correspAction type="received">
<persName key="william"/>
</correspAction>
</correspDesc>
<text/>
</TEI>
<TEI correspondence="anna" xml:id="5">
<correspDesc>
<correspAction type="sent">
<persName key="william"/>
<persName key="charlotte"/>
<persName key="bertram"/>
</correspAction>
<correspAction type="received">
<persName key="anna"/>
</correspAction>
</correspDesc>
<text/>
</TEI>
<TEI correspondence="anna" xml:id="6">
<correspDesc>
<correspAction type="sent">
<persName key="abraham"/>
<persName key="anna"/>
</correspAction>
<correspAction type="received">
<persName key="william"/>
</correspAction>
</correspDesc>
<text/>
</TEI>
<TEI correspondence="bertram" xml:id="3">
<correspDesc>
<correspAction type="sent">
<persName key="william"/>
</correspAction>
<correspAction type="received">
<persName key="bertram"/>
</correspAction>
</correspDesc>
<text/>
</TEI>
<TEI correspondence="charlotte" xml:id="4">
<correspDesc>
<correspAction type="sent">
<persName key="charlotte"/>
<persName key="anna"/>
</correspAction>
<correspAction type="received">
<persName key="william"/>
</correspAction>
</correspDesc>
<text/>
</TEI>
<TEI correspondence="charlotte" xml:id="7">
<correspDesc>
<correspAction type="sent">
<persName key="abraham"/>
<persName key="william"/>
</correspAction>
<correspAction type="received">
<persName key="charlotte"/>
</correspAction>
</correspDesc>
</TEI>
</root>
Не уверен, что вы можете использовать XSLT 3 (доступно после Saxon 9.8), ноконечно, легко создать некоторую XML-структуру в XSLT вместо параметра array(xs:string*)
, как показано в http://xsltransform.net/asnmyG:
<xsl:param name="person-groups">
<group>
<person>anna</person>
<person>abraham</person>
</group>
<group>
<person>bertram</person>
</group>
<group>
<person>charlotte</person>
</group>
</xsl:param>
<xsl:template match="/*">
<xsl:variable name="root" select="."/>
<xsl:copy>
<xsl:for-each select="$person-groups/group">
<xsl:apply-templates
select="key('sent-by', person, $root) intersect $received-by-william |
key('received-by', person, $root) intersect $sent-by-william">
<xsl:with-param name="correspondence" select="person[1]"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:template>
Конечно, как массив XPath 3.1, так и структура XSLT 2 XML могут бытьпостроить из вашего пробела / разделенных тиреПри необходимости выполните последовательность, например, в http://xsltransform.net/asnmyG/1 с
<xsl:param name="persons">anna-abraham bertram charlotte</xsl:param>
<xsl:param name="person-groups">
<xsl:for-each select="tokenize($persons, '\s+')">
<group>
<xsl:for-each select="tokenize(., '-')">
<person>
<xsl:value-of select="."/>
</person>
</xsl:for-each>
</group>
</xsl:for-each>
</xsl:param>
или в https://xsltfiddle.liberty -development.net / pPzifp2 / 8 с
<xsl:param name="persons-string">anna-abraham bertram charlotte</xsl:param>
<xsl:param name="persons" as="array(xs:string*)"
select="array:join(tokenize($persons-string, '\s+') ! [ tokenize(., '-') ])"/>