2011-12-27 251 views
1

我必须变换,其具有以下结构XSLT使用信息从一个兄弟在另一个

<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我尝试合并两个节点时,属性“d”等于一个XML文档

<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="[email protected] eq @d"> 
       <xsl:value-of select="[email protected]" /> 
      </xsl:if> 
     </xsl:for-each>   
    </xsl:element> 
</xsl:element> 

因此,if语句显然不起作用,但我该怎么做呢?

回答

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用于分组。

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> 
+0

看来你还没有运行这个转换 - 它甚至不是格式良好的XML文档,并且有许多句法错误会阻止这个c甚至可以解析。 – 2011-12-28 17:38:24

+0

你是对的,5个小错误已被纠正,代码转贴。 – 2011-12-28 17:55:38

+0

FirstZero,如果有三个'NodeX'元素具有相同的'd'属性值,则您的解决方案会创建两个'NewNode'元素。然而,想要的结果是将所有这些合并成一个'NewNode'元素。 – 2011-12-28 19:09:04