2017-10-23 9 views
1

私はxsltでかなり新しく、本当に面倒なグループマージのケースを見つけました。私は、次のXML構造:特定の子ノードに基づいて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> 

を、私はそれがCの名前の子セクションを含むセクションに直面するまでのコードだけROW1をマージしなければならないような方法でそれを変換する必要があります。

<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]" /> 

私を助けてください。私は今のところちょうどすべてのセクション内のすべての行をマージしている何

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

。まあ

答えて

0

、XSLT 2.0とあなたがfor-each-groupgroup-bygroup-adjacentgroup-starting/ending-withのようなその様々なオプション付き(https://www.w3.org/TR/xslt20/#grouping-examples)自分でおなじみ確認する必要があり、その後、あなたは

<?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> 
を出力
<?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> 

を思い付くことができます

+0

これは宝石のように機能しますが、for-eachループに関する小さな質問がありました。ループはノードを処理する順序を保持しているのか、それとも現在のグループ(current-group)それは何ですか? – V15720002000

+0

あなたは 'for-each-group'について質問していますか? 'select =" * 'によって選択された集団集団を集団順に処理し、グループの後に集団を形成します。詳細については、https://www.w3.org/TR/xslt20/#xsl-for-each-groupを参照してください。 –

関連する問題