这就是我的XML的样子
<?xml version="1.0"?>
<Nodes>
<NodeA NodeAattr="123">
<NodeB NodeBattr="456"></NodeB>
<NodeC>
<NodeD NodeDAttr="ValueD">
<NodeE Name="ValueABC"> "555" </NodeE >
<NodeE Name="ValueABC"> "666" </NodeE>
</NodeD>
</NodeC>
</NodeA>
</Nodes>
如果NodeE的Name属性值相同,则连接NodeE的值。 我的最终输出xml必须看起来像
<NodeA NodeAattr="123">
<NodeB NodeBattr="456"></NodeB>
<NodeC>
<NodeD="ValueD">
<NodeE Name="ValueABC"> "555" , "666" </NodeE >
</NodeD>
</NodeC>
</NodeA>
请向我提供xsl ..我正在使用XSLT1.0
答案 0 :(得分:2)
这应该这样做:
<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:strip-space elements="*" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="NodeE">
<xsl:copy>
<xsl:apply-templates select="@* | text()" />
<xsl:call-template name="NextSibling" />
</xsl:copy>
</xsl:template>
<xsl:template match="NodeE[@Name = preceding-sibling::*[1][self::NodeE]/@Name]" />
<xsl:template match="NodeE" mode="includeSib">
<xsl:value-of select="concat(',', .)"/>
<xsl:call-template name="NextSibling" />
</xsl:template>
<xsl:template name="NextSibling">
<xsl:apply-templates
select="following-sibling::*[1]
[self::NodeE and @Name = current()/@Name]"
mode="includeSib" />
</xsl:template>
</xsl:stylesheet>
在此输入上运行时(带有一些其他值来演示其功能):
<Nodes>
<NodeA NodeAattr="123">
<NodeB NodeBattr="456"></NodeB>
<NodeC>
<NodeD NodeDAttr="ValueD">
<NodeE Name="ValueABC"> "555" </NodeE >
<NodeE Name="ValueABC"> "666" </NodeE>
<NodeE Name="ValueDEF"> "555" </NodeE >
<NodeE Name="ValueDEF"> "565" </NodeE >
<NodeE Name="ValueDEF"> "575" </NodeE >
<NodeE Name="ValueABC"> "595" </NodeE >
</NodeD>
</NodeC>
</NodeA>
</Nodes>
结果是:
<Nodes>
<NodeA NodeAattr="123">
<NodeB NodeBattr="456" />
<NodeC>
<NodeD NodeDAttr="ValueD">
<NodeE Name="ValueABC"> "555" , "666" </NodeE>
<NodeE Name="ValueDEF"> "555" , "565" , "575" </NodeE>
<NodeE Name="ValueABC"> "595" </NodeE>
</NodeD>
</NodeC>
</NodeA>
</Nodes>
答案 1 :(得分:1)
以下是基于我对question #825783的回答的解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kNode" match="NodeE" use="@Name"/>
<!--
Identity transform: copy elements and attributes from input file as is
-->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<!--
Use Muenchian grouping to apply unique NodeE elements.
See http://www.jenitennison.com/xslt/grouping/muenchian.html
-->
<xsl:template match="NodeE[generate-id() =
generate-id(key('kNode', @Name)[1])]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<!--
Apply <NodeE> elements with the same @Name attribute value as the current
element with the "concat" mode enabled
-->
<xsl:apply-templates select="key('kNode', @Name)" mode="concat"/>
</xsl:copy>
</xsl:template>
<xsl:template match="NodeE" mode="concat">
<xsl:value-of select="."/>
<!-- Add comma except if this is the last node -->
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:template>
<!-- Drop other <NodeE> elements -->
<xsl:template match="NodeE"/>
</xsl:stylesheet>
使用JLRishe提供的输入:
<Nodes>
<NodeA NodeAattr="123">
<NodeB NodeBattr="456"></NodeB>
<NodeC>
<NodeD NodeDAttr="ValueD">
<NodeE Name="ValueABC"> "555" </NodeE>
<NodeE Name="ValueABC"> "666" </NodeE>
<NodeE Name="ValueDEF"> "555" </NodeE>
<NodeE Name="ValueDEF"> "565" </NodeE>
<NodeE Name="ValueDEF"> "575" </NodeE>
<NodeE Name="ValueABC"> "595" </NodeE>
</NodeD>
</NodeC>
</NodeA>
</Nodes>
这与JLRishe的输出不同,因为我对要求的理解不同:
<?xml version="1.0" encoding="utf-8"?>
<Nodes>
<NodeA NodeAattr="123">
<NodeB NodeBattr="456"/>
<NodeC>
<NodeD NodeDAttr="ValueD">
<NodeE Name="ValueABC"> "555" , "666" , "595" </NodeE>
<NodeE Name="ValueDEF"> "555" , "565" , "575" </NodeE>
</NodeD>
</NodeC>
</NodeA>
</Nodes>