Я думаю, что вы можете написать рекурсивную функцию по ссылке, которую лучше всего использовать с помощью клавиши:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="3.0">
<xsl:param name="start-id">15492293</xsl:param>
<xsl:output method="text"/>
<xsl:key name="parent" match="related-documents/*" use="relation/child-doc/document-id/doc-number"/>
<xsl:function name="mf:get-ancestor-ids" as="xs:integer*">
<xsl:param name="item" as="element()"/>
<xsl:sequence
select="let $parent-id := $item/relation/parent-doc/document-id/doc-number,
$parent := key('parent', $parent-id, root($item))
return (xs:integer($parent-id), $parent!mf:get-ancestor-ids(.))"/>
</xsl:function>
<xsl:template match="/" name="xsl:initial-template">
<xsl:value-of select="$start-id, mf:get-ancestor-ids(key('parent', $start-id))" separator=" -> "/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty -development.net / eiZQaF1 дает результат
15492293 -> 14711658 -> 14473159 -> 13911616 -> 12823700 -> 10665793 -> 9861196 -> 9861326
В этом примере используются некоторые функции XSLT и XPath 3, например let
или !
, но вы, конечно, можете переписать это для XSLT и XPath 2.0, используя xsl:variable
вместо let
и $parent/mf:get-ancestor-ids(.)
или if ($parent) then mf:get-ancestor-ids($parent) else ()
для $parent!mf:get-ancestor-ids(.)
:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:param name="start-id">15492293</xsl:param>
<xsl:output method="text"/>
<xsl:key name="parent" match="related-documents/*" use="relation/child-doc/document-id/doc-number"/>
<xsl:function name="mf:get-ancestor-ids" as="xs:integer*">
<xsl:param name="item" as="element()"/>
<xsl:variable name="parent-id"
select="$item/relation/parent-doc/document-id/doc-number"/>
<xsl:variable name="parent"
select="key('parent', $parent-id, root($item))"/>
<xsl:sequence
select="xs:integer($parent-id), $parent/mf:get-ancestor-ids(.)"/>
</xsl:function>
<xsl:template match="/">
<xsl:value-of select="$start-id, mf:get-ancestor-ids(key('parent', $start-id))" separator=" -> "/>
</xsl:template>
</xsl:stylesheet>
http://xsltransform.net/93nvfd2