Xml 查找所有相关元素的XSLT
我试图找出是否可以使用XSLT转换以下XML(代码段,因为它包含更多元素),以便转换后的XML只包含在子元素中指定的内容元素Xml 查找所有相关元素的XSLT,xml,xslt,xslt-1.0,xslt-2.0,xslt-3.0,Xml,Xslt,Xslt 1.0,Xslt 2.0,Xslt 3.0,我试图找出是否可以使用XSLT转换以下XML(代码段,因为它包含更多元素),以便转换后的XML只包含在子元素中指定的内容元素 <?xml version="1.0" encoding="UTF-8"?> <library> <content content-id="a"> <content-link content-id="a1"/>
<?xml version="1.0" encoding="UTF-8"?>
<library>
<content content-id="a">
<content-link content-id="a1"/>
<content-link content-id="a2"/>
</content>
<content content-id="b">
<content-link content-id="b1"/>
<content-link content-id="b2"/>
</content>
<content content-id="a1">
<content-link content-id="a11"/>
<content-link content-id="a12"/>
</content>
<content content-id="a2">
<content-link content-id="a21"/>
<content-link content-id="a22"/>
</content>
<content content-id="a11"/>
<content content-id="a12"/>
<content content-id="a21"/>
<content content-id="a22"/>
</library>
到
下面是我的尝试,但我在XSLT方面相当薄弱,因此在此感谢您的进一步投入
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="cid" select="'a'" />
<xsl:template match="/">
<library>
<xsl:apply-templates select="//content[@content-id=$cid]"/>
</library>
</xsl:template>
<xsl:template match="content">
<xsl:copy-of select="." />
<xsl:for-each select="*">
<xsl:apply-templates select="content-link"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="content-link">
<!-- Don't know how to call the ancestor content elements referenced by content-link -->
</xsl:template>
</xsl:stylesheet>
可能是这样的:
<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 ! (. | content-link | key('ref', 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>
请详细解释此处需要应用的逻辑。感谢Martin,您的XSLT绝对有帮助!我刚刚意识到我的内容链接元素是一个孙子,如下面的示例片段所示:但是我没有足够的技能进行正确的更改,因此不知道您是否可以在这里提供帮助。我设法解决了更改,因为我无法输出其他元素的唯一未决问题除了和。当然,如果您能帮助指出此处需要修改的内容,我们将不胜感激。@RoyTan,一般来说,回答后不要试图更改您的要求。取而代之的是,提出一个包含必要细节的新问题。对于链接到的示例,请检查中的更改是否符合您的要求。如果没有,请提出一个新问题,详细说明可能的输入结构以及哪些元素需要复制,哪些元素不需要复制。感谢Martin,他在下次发布新问题时指出。更新的更改解决了问题,所以这里一切都很好。
<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 ! (. | content-link | key('ref', 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>