Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于特定子节点对xml节点进行分组和合并_Xml_Xslt 2.0 - Fatal编程技术网

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

基于特定子节点对xml节点进行分组和合并,xml,xslt-2.0,Xml,Xslt 2.0,我是xslt新手,遇到了一个非常棘手的组合并案例。我有以下xml结构: <root> <section name="A"> <table name="B"> <row1/> </table> </section> <section name="A"> <table name="B"> <row1/> </tabl

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

我需要对它进行转换,使代码只合并行1,直到它遇到一个包含名为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]" />


请帮帮我。

好吧,使用XSLT 2.0,您应该熟悉每个组的
,以及它的各种选项,如
groupby
groupinnexted
groupstart/end 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>

好的,使用XSLT 2.0,您应该熟悉每个组的
,以及它的各种选项,如
groupby
groupinnexted
groupstart/end 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>


谢谢,这就像一块宝石,但是我有一个关于for each循环的小问题:循环是否保留了处理节点的顺序,还是保留了处理节点的current-group()函数?您是在询问每个组的
?它以填充顺序处理由
select=“*
选择的分组填充,并形成一个又一个组。有关详细信息,请参阅。感谢这像gem一样工作,但是我有一个关于for each循环的小问题:循环是否保留处理节点的顺序,还是当前的-group()哪个函数执行此操作?您是否询问每个组的
?它按填充顺序处理
select=“*
选择的分组填充,并形成一个组接一个组。有关详细信息,请参阅。