Reputation: 25
As per http://xsltfiddle.liberty-development.net/jxNakA5/1, I am missing the following descendant node in the output:
<test-child>123</test-child>
Any idea what can be wrong here?
Source XML
?xml version="1.0" encoding="UTF-8"?>
<library>
<content content-id="a">
<test>
<test-child>123</test-child>
</test>
<data xml:lang="x-default">{"product" : 123 }</data>
<content-links>
<content-link content-id="a1"/>
<content-link content-id="a2"/>
</content-links>
</content>
<content content-id="b">
<data xml:lang="x-default">{"product" : 123 }</data>
<content-links>
<content-link content-id="b1"/>
<content-link content-id="b2"/>
</content-links>
</content>
<content content-id="a1">
<data xml:lang="x-default">{"product" : 123 }</data>
<content-links>
<content-link content-id="a11"/>
<content-link content-id="a12"/>
</content-links>
</content>
<content content-id="a2">
<data xml:lang="x-default">{"product" : 123 }</data>
<content-links>
<content-link content-id="a21"/>
<content-link content-id="a22"/>
</content-links>
</content>
<content content-id="a11">
<data xml:lang="x-default">{"product" : 123 }</data>
</content>
<content content-id="a12"/>
<content content-id="a21">
<data xml:lang="x-default">{"product" : 123 }</data>
</content>
</library>
XSLT
<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="#all"
version="3.0">
<xsl:function name="mf:get-related-elements" as="element()*">
<xsl:param name="element" as="element()"/>
<xsl:sequence
select="$element ! (. | * | key('ref', content-links/content-link/@content-id)/mf:get-related-elements(.))"/>
</xsl:function>
<xsl:key name="ref" match="/*//*" use="@content-id"/>
<xsl:param name="cid" select="'a'" />
<xsl:variable name="start" select="key('ref', $cid)"/>
<xsl:variable name="related-elements" select="mf:get-related-elements($start)"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="/*//*[not(. intersect $related-elements)]"/>
</xsl:stylesheet>
Upvotes: 0
Views: 50
Reputation: 163595
Well, it's pretty clear why it isn't being copied: it's not a "related element".
I don't know what you're trying to achieve (you haven't told us), but your code is treating children as related, but not deeper descendants. The function follows the relationship through @content-id recursively, but it doesn't recurse when selecting the children of the supplied element, so only the first-level children are selected.
Upvotes: 1
Reputation: 167716
See whether using
<xsl:sequence
select="$element ! (. | .//* | key('ref', content-links/content-link/@content-id)/mf:get-related-elements(.))"/>
works for your latest requirement.
But it is hard to tell whether the original approach patched each time you add a requirement is the right way to go unless you start describing with some sentences what the criteria are to copy and not to copy nodes through to the output.
Upvotes: 1