XSLT использует информацию от одного брата в другом - PullRequest
1 голос
/ 27 декабря 2011

Мне нужно преобразовать документ 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 я пытаюсь объединить два узла, когда атрибут "d" равен

<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 явно не работает, но как я могу сделать это иначе?

Ответы [ 2 ]

2 голосов
/ 27 декабря 2011

Это преобразование :

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

Объяснение : Метод Мюнхена для группировки.

0 голосов
/ 28 декабря 2011

Вот альтернативный способ сделать это, вы можете использовать два для каждого, чуть менее элегантно, чем @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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...