2011-12-27 234 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