合并XML节点

时间:2011-11-02 20:57:12

标签: xslt

我有一个源xml,格式如下:

 <xml>
   <node>
         <va-name>
               <source area="RSC1985s5c1"/>
         </va-name>
         <body>
              <div >
                  <heading>heading 1</heading>
               </div>
         </body>
   </node>
   <node>
         <va-name>
               <source area="RSC1985s5c2"/>
         </va-name>
         <body>
              <div >
                  <heading>heading 2</heading>
               </div>
         </body>
   </node>

   <node>
         <va-name>
               <source area="RSC1985s5c1"/>
         </va-name>
         <body>
              <div >
                  <heading>heading 3</heading>
               </div>
         </body>
   </node>

<xml>

如果xml / node / va-name / source [@area]值在不同的xml / node之间相等,我想要的是合并节点。我只需要复制xml / node / body并将它们合并到第一个节点。

输出应为:

 <xml>
   <node>
         <va-name>
               <source area="RSC1985s5c1"/>
         </va-name>
         <body>
              <div >
                  <heading> heading 1 </heading>
               </div>
               <div >
                  <heading> heading 3 </heading>
               </div>
         </body>
   </node>
    <node>
         <va-name>
               <source area="RSC1985s5c2"/>
         </va-name>
         <body>
              <div >
                  <heading>heading 2</heading>
               </div>
         </body>
   </node>
 </xml>

在上面的输出中,节点1和节点3具有相同的xml / node / va-name / source [@area],这就是为什么在输出中我已经将两者组合在一起,并且节点2将按原样输出。如果我有更多的节点,并且如果其中任何一个节点匹配(xml / node / va-name / source [@area]),那么我们将它与节点2结合起来,依此类推......

感谢我能得到任何帮助......

2 个答案:

答案 0 :(得分:1)

XSLT 2.0中非常简单的分组解决方案:

<xsl:template match="xml">
<xml>
  <xsl:for-each-group select="node" group-by="va-name/source/@area">
  <node>
    <xsl:copy-of select="va-name"/>
    <body>
      <xsl:copy-of select="current-group()/body/*"/>
    </body>
  </node>
  </xsl:for-each-group>
</xml>
</xsl:template>

答案 1 :(得分:0)

这是使用Muenchian method最佳解决的YAGP(又一个分组问题)。此样式表生成所需的输出:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="byArea" match="node" use="va-name/source/@area" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template
        match="node[generate-id()=
                    generate-id(key('byArea', va-name/source/@area)[1])]">
        <node>
            <xsl:apply-templates select="va-name" />
            <body>
                <xsl:apply-templates select="key('byArea', va-name/source/@area)"
                    mode="out" />
            </body>
        </node>
    </xsl:template>
    <xsl:template match="node" mode="out">
        <xsl:apply-templates select="body/div" />
    </xsl:template>
    <xsl:template match="node" />
</xsl:stylesheet>