我必须转换具有以下结构的XML文档
<NODEA d="8" m="1" xxxxx="WWWWWWWWWWWWWW"/>
<NODEA d="16" m="1" xxxxx="somethingelse"/>
<NODEB d="1" m="1" yyyyy="xx"/>
<NODEB d="2" m="1" yyyyy="xx"/>
<NODEB d="3" m="1" yyyyy="yy"/>
<NODEB d="4" m="1" yyyyy="zz"/>
<NODEB d="5" m="1" yyyyy="aa"/>
<NODEB d="6" m="1" yyyyy="ss"/>
<NODEB d="7" m="1" yyyyy="33"/>
<NODEB d="8" m="1" yyyyy="AAAAAAAAAAAAA"/>
<NODEB d="9" m="1" yyyyy="qq"/> etc
在xslt中我尝试合并两个节点,当属性&#34; d&#34;是平等的
<NewNode>
<d>8</d>
<m>1</m>
<xxxxx>WWWWWWWWWWWWWW</xxxxx>
<yyyyy>AAAAAAAAAAAAA</yyyyy>
</NewNode>
这样做
<xsl:template match="NODEB">
<xsl:element name="NewNode">
<xsl:apply-templates select="@d" />
<xsl:apply-templates select="@m" />
<xsl:apply-templates select="@yyyyy" />
<xsl:element name="xxxxx" >
<xsl:for-each select="//NODEA">
<xsl:if test=".@d eq @d">
<xsl:value-of select=".@xxxxx" />
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:element>
所以if语句显然不起作用,但我怎么能这样做呢?
答案 0 :(得分:2)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kElemByD" match="*" use="@d"/>
<xsl:template match="node()|@*" priority="-1">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template priority="1" match=
"*[generate-id()
=
generate-id(key('kElemByD', @d)[2])
]
">
<newNode>
<xsl:copy-of select="key('kElemByD', @d)/@*"/>
</newNode>
</xsl:template>
<xsl:template match=
"*[count(key('kElemByD', @d)) > 1]"/>
</xsl:stylesheet>
应用于提供的XML (包装到顶部元素中以成为格式良好的XML文档):
<t>
<NODEA d="8" m="1" xxxxx="WWWWWWWWWWWWWW"/>
<NODEA d="16" m="1" xxxxx="somethingelse"/>
<NODEB d="1" m="1" yyyyy="xx"/>
<NODEB d="2" m="1" yyyyy="xx"/>
<NODEB d="3" m="1" yyyyy="yy"/>
<NODEB d="4" m="1" yyyyy="zz"/>
<NODEB d="5" m="1" yyyyy="aa"/>
<NODEB d="6" m="1" yyyyy="ss"/>
<NODEB d="7" m="1" yyyyy="33"/>
<NODEB d="8" m="1" yyyyy="AAAAAAAAAAAAA"/>
<NODEB d="9" m="1" yyyyy="qq"/>
</t>
生成想要的正确结果:
<t>
<NODEA d="16" m="1" xxxxx="somethingelse"/>
<NODEB d="1" m="1" yyyyy="xx"/>
<NODEB d="2" m="1" yyyyy="xx"/>
<NODEB d="3" m="1" yyyyy="yy"/>
<NODEB d="4" m="1" yyyyy="zz"/>
<NODEB d="5" m="1" yyyyy="aa"/>
<NODEB d="6" m="1" yyyyy="ss"/>
<NODEB d="7" m="1" yyyyy="33"/>
<newNode d="8" m="1" xxxxx="WWWWWWWWWWWWWW" yyyyy="AAAAAAAAAAAAA"/>
<NODEB d="9" m="1" yyyyy="qq"/>
</t>
解释: Muenchian method 进行分组。
答案 1 :(得分:0)
这是另一种方法,你可以使用两个for-each,比@Dimitre更不优雅:)
<强> EDITED 强>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<xsl:for-each select="//NODEA">
<xsl:variable name="nodea" select="."/>
<xsl:variable name="d" select="./@d"/>
<!-- The d should match only then create New Node -->
<xsl:for-each select="//NODEB[@d = $d]">
<xsl:variable name="nodeb" select="." />
<NewNode>
<d><xsl:value-of select="$d"/></d>
<m><xsl:value-of select="$nodea/@m"/></m>
<xxxxx><xsl:value-of select="$nodea/@xxxxx"/></xxxxx>
<yyyyy><xsl:value-of select="$nodeb/@yyyyy"/></yyyyy>
</NewNode>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
产生必要的输出
<NewNode>
<d>8</d>
<m>1</m>
<xxxxx>WWWWWWWWWWWWWW</xxxxx>
<yyyyy>AAAAAAAAAAAAA</yyyyy>
</NewNode>