我正在尝试将新节点下的重复节点分组(按排序顺序)。这是我的xml。
<NodeRoot>
<NodeA>
<NodeB>
<NodeC>101</NodeC>
<NodeC>102</NodeC>
<NodeC>101</NodeC>
<NodeC>104</NodeC>
</NodeB>
</NodeA>
<NodeA>
<NodeB>
<NodeC>102</NodeC>
<NodeC>103</NodeC>
<NodeC>101</NodeC>
<NodeC>102</NodeC>
</NodeB>
</NodeA>
</NodeRoot>
这就是我想要实现的目标。请注意,首先对重复的NodeC进行排序,然后将其分组到新的NodeGroup节点下。
<NodeRoot>
<NodeA>
<NodeB>
<NodeGroup>
<NodeC>101</NodeC>
<NodeC>101</NodeC>
</NodeGroup>
<NodeGroup>
<NodeC>102</NodeC>
</NodeGroup>
<NodeGroup>
<NodeC>104</NodeC>
</NodeGroup>
</NodeB>
</NodeA>
<NodeA>
<NodeB>
<NodeGroup>
<NodeC>101</NodeC>
</NodeGroup>
<NodeGroup>
<NodeC>102</NodeC>
<NodeC>102</NodeC>
</NodeGroup>
<NodeGroup>
<NodeC>103</NodeC>
</NodeGroup>
</NodeB>
</NodeA>
</NodeRoot>
这是我的xslt(我只能访问xslt1)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="NodeB">
<NodeB>
<xsl:apply-templates select="NodeB[not(NodeC = preceding-sibling::NodeB/NodeC)]" mode="GroupC">
<xsl:sort select="NodeC" data-type="number"/>
</xsl:apply-templates>
</NodeB>
</xsl:template>
<xsl:template match="NodeB" mode="GroupC">
<xsl:variable name="GC" select="NodeC"/>
<NodeB>
<NodeGroup>
<xsl:apply-templates select="NodeB[NodeC/text()=$GC]" mode="SameC" />
</NodeGroup>
</NodeB>
</xsl:template>
<xsl:template match="NodeC" mode="SameC">
<xsl:copy-of select="NodeC"/>
</xsl:template>
</xsl:stylesheet>
这不是对重复的NodeC进行分组。有人可以帮忙吗?
答案 0 :(得分:1)
如果你想对前面的兄弟姐妹采取这种方法,那么你只需要确保你处理NodeC
孩子:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="NodeB">
<NodeB>
<xsl:apply-templates select="NodeC[not(. = preceding-sibling::NodeC)]" mode="GroupC">
<xsl:sort select="." data-type="number"/>
</xsl:apply-templates>
</NodeB>
</xsl:template>
<xsl:template match="NodeC" mode="GroupC">
<NodeGroup>
<xsl:copy-of select="../NodeC[. = current()]"/>
</NodeGroup>
</xsl:template>
</xsl:stylesheet>
甚至不需要额外的模式。
使用Muenchian grouping在XSLT 1.0中进行分组通常更有效,尽管在这里您需要一个密钥,将NodeB
父级的生成ID与NodeC
值连接起来,以便识别NodeB
的子树内的组:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="group" match="NodeC" use="concat(generate-id(..), '|', .)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="NodeB">
<NodeB>
<xsl:apply-templates select="NodeC[generate-id() = generate-id(key('group', concat(generate-id(..), '|', .))[1])]" mode="GroupC">
<xsl:sort select="." data-type="number"/>
</xsl:apply-templates>
</NodeB>
</xsl:template>
<xsl:template match="NodeC" mode="GroupC">
<NodeGroup>
<xsl:copy-of select="key('group', concat(generate-id(..), '|', .))"/>
</NodeGroup>
</xsl:template>
</xsl:stylesheet>