我周围搜索,发现这个网站上很多帖子是有用的让我这么远。确定独特的子节点数XSLT
我想使用xslt来组合元素和他们的孩子共享一个共同的属性值。我设法使用xsl:keys来完成此操作。
我坚持的部分是我也需要实质上重现原始树,除非具有特定属性的父元素匹配我生成的组合结构,那么父元素应该没有子元素。你可以在提供的示例输入/输出中看到这一点。输出第二部分中的<parent attribute="two"/>
没有孩子,因为它最初包含所有孩子。
XML输入格式:
<root>
<parent attribute="one">
<child>one</child>
<child>two</child>
<child>three</child>
</parent>
<parent attribute="two">
<child>one</child>
<child>two</child>
<child>three</child>
</parent>
<parent attribute="one">
<child>two</child>
<child>three</child>
<child>four</child>
</parent>
<extra>
<extra>
<parent attribute="two">
<child>three</child>
</parent>
</extra>
</extra>
</root>
所需的输出格式:
<root>
<first>
<new attribute="one">
<child>one</child>
<child>two</child>
<child>three</child>
<child>four</child>
</new>
<new attribute="two">
<child>one</child>
<child>two</child>
<child>three</child>
</new>
</first>
<second>
<parent attribute="one">
<child>one</child>
<child>two</child>
<child>three</child>
</parent>
<parent attribute="two"/>
<parent attribute="one">
<child>two</child>
<child>three</child>
<child>four</child>
</parent>
<extra>
<extra>
<parent attribute="two">
<child>three</child>
</parent>
</extra>
</extra>
</second>
</root>
我涉及重新使用用于输出的第一部分中创建的密钥当前尝试。我的目标是简单地比较总的唯一的子数与当前的父母子数,以确定当前的父节点是否包含所有组合的子节点。我已经尝试了很多类似的方法来产生如下所示的组合计数,但我开始认为我错误地解决了这个问题,因为我要么返回每个子元素的计数,要么返回当前父元素子元素的计数。
我还没有考虑保留第二部分的原始结构的其余部分,因为这不是当时的紧迫问题。
任何意见,将不胜感激。如果我不善于搜索,而其他人有类似的问题,请随时指导我。
XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="ParentKey" match="parent" use="@attribute"/>
<xsl:key name="ChildKey" match="parent/child" use="../@attribute"/>
<xsl:template match="@*|node()">
<xsl:apply-templates select="@*|node()" />
</xsl:template>
<xsl:template match="/">
<xsl:element name="first">
<xsl:for-each select="//parent[count(. | key('ParentKey', @attribute)[1]) = 1]">
<xsl:element name="new">
<xsl:attribute name="attribute">
<xsl:value-of select="@attribute"/>
</xsl:attribute>
<xsl:apply-templates select="child[count(. | key('ChildKey', @attribute)[1]) = 1]"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
<xsl:element name="second">
<xsl:apply-templates select="//parent" mode="second"/>
</xsl:element>
</xsl:template>
<xsl:template match="child">
<xsl:element name="child">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="parent" mode="second">
<xsl:element name="parent">
<xsl:attribute name="attribute">
<xsl:value-of select="@attribute"/>
</xsl:attribute>
<!-- currently problematic line -->
<xsl:variable name="combinedCount" select="count(//parent/child[count(. | key('ChildKey', @attribute)[1]) = 1])"/>
<xsl:variable name="currentCount" select="count(child)"/>
<xsl:if test="not($combinedCount = $currentCount)">
<xsl:apply-templates select="child"/>
</xsl:if>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
对于特定的问题(但对于所有XSLT问题),您需要明确您是否使用XSLT 1.0或2.0。解决方案可能非常不同。 –