基于特定子节点对xml节点进行分组和合并

时间:2017-10-23 21:51:55

标签: xml xslt-2.0

我在xslt中相当新,遇到了一个非常棘手的小组合并案例。我有一个以下的xml结构:

<root>
  <section name="A"> 
    <table name="B">
      <row1/>
    </table>
  </section>
  <section name="A"> 
    <table name="B">
      <row1/>
    </table>
  </section>
  <section name="A"> 
    <table name="B">
      <row1/>
    </table>
    <section name="C"></section>
  </section>
  <section name="A"> 
    <table name="B">
      <row1/>
    </table>
  </section>
  <section name="A"> 
    <table name="B">
      <row1/>
    </table>
  </section>
</root>

我需要以一种方式对其进行转换,使得代码只应合并row1,直到它面对包含名称为c的子节的节:

<root>
   <section name="A"> 
     <table name="B">
       <row1/>
       <row1/>
     </table>
   </section>
   <section name="A"> 
     <table name="B">
      <row1/>
     </table>
     <section name="C"></section>
   </section>
    <section name="A"> 
     <table name="B">
       <row1/>
       <row1/>
     </table>
   </section>
</root>

到目前为止,我只是合并了所有部分中的所有行:

<xsl:template match="section[@name='A' and following-sibling::section[@name='A'] ]//table[1]" >
   <xsl:copy>
        <xsl:apply-templates select="@*" />
                        <xsl:apply-templates select="ancestor::section[@name='A']/following-sibling::section[@name='A']//table[1]/row1" />
    </xsl:copy>
</xsl:template>
<xsl:template match="section[ @name='A' and preceding-sibling::section[@name='A'] ]//table[1]" />

请帮帮我。

1 个答案:

答案 0 :(得分:0)

嗯,使用XSLT 2.0,您应该熟悉for-each-group)与group-by及其各种选项,如group-adjacentgroup-starting/ending-with以及<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="@* | node()" mode="#all"> <xsl:copy> <xsl:apply-templates select="@* , node()" mode="#current"/> </xsl:copy> </xsl:template> <xsl:template match="root"> <xsl:copy> <xsl:for-each-group select="*" group-adjacent="boolean(self::section[@name = 'A' and not(section[@name = 'C'])])"> <xsl:choose> <xsl:when test="current-grouping-key()"> <xsl:apply-templates select="." mode="merge"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="current-group()"/> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </xsl:copy> </xsl:template> <xsl:template match="row1" mode="merge"> <xsl:copy-of select="current-group()//row1"/> </xsl:template> </xsl:stylesheet> ,然后你可以拿出

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <section name="A">
      <table name="B">
         <row1/>
         <row1/>
      </table>
   </section>
   <section name="A">
      <table name="B">
         <row1/>
      </table>
      <section name="C"/>
   </section>
   <section name="A">
      <table name="B">
         <row1/>
         <row1/>
      </table>
   </section>
</root>

输出

{{1}}