XSLT 查找所有相关元素
XSLT to find all related elements
我正在尝试确定是否可以使用 XSLT 来转换以下 XML(代码段,因为它包含更多元素),以便转换后的 XML 仅包含以下内容元素在子元素中指定。
<?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>
至
<?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="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>
我正在尝试确定是否可以使用 XSLT 来转换以下 XML(代码段,因为它包含更多元素),以便转换后的 XML 仅包含以下内容元素在子元素中指定。
<?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>
至
<?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="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>