3

私はxslが初めてです。似たようなものを見つけましたが、自分の用途に合わせて微調整することはできません。

入力:

<section>
  <heading>some heading text</heading>
  <amendment chapter="1">
    <foo/>
  </amendment>
  <amendment chapter="2">
    <bar/>
  </amendment>
  <amendment chapter="3">
    <baz/>
  </amendment>
  <heading>some heading text</heading>
  <amendment chapter="1">
    <baz/>
  </amendment>
</section>

属性 "chapter='1' または chapter='2'" を持つ要素をラップするには。出力:

<section>
  <heading>some heading text</heading>
  <newwrapper>
    <amendment chapter="1">
      <foo/>
    </amendment>
    <amendment chapter="2">
      <bar/>
    </amendment>
  </newwrapper>
  <amendment chapter="3">
    <baz/>
  </amendment>
  <heading>some heading text</heading>
  <newwrapper>
    <amendment chapter="1">
      <baz/>
    </amendment>
  </newwrapper>
</section>
4

2 に答える 2

1

I. この XSLT 2.0 変換:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
   <section>
    <xsl:for-each-group select="*" 
                        group-adjacent="self::amendment and @chapter =(1,2)">
     <xsl:choose>
       <xsl:when test="current-grouping-key()">
         <newwrapper>
           <xsl:sequence select="current-group()"/>
         </newwrapper>
       </xsl:when>
       <xsl:otherwise>
         <xsl:sequence select="current-group()"/>
       </xsl:otherwise>
     </xsl:choose>
    </xsl:for-each-group>
  </section>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントに適用した場合:

<section>
    <heading>some heading text</heading>
    <amendment chapter="1">
        <foo/>
    </amendment>
    <amendment chapter="2">
        <bar/>
    </amendment>
    <amendment chapter="3">
        <baz/>
    </amendment>
    <heading>some heading text</heading>
    <amendment chapter="1">
        <baz/>
    </amendment>
</section>

必要な正しい結果が生成されます。

<section>
   <heading>some heading text</heading>
   <newwrapper>
      <amendment chapter="1">
               <foo/>
         </amendment>
      <amendment chapter="2">
               <bar/>
         </amendment>
   </newwrapper>
   <amendment chapter="3">
            <baz/>
      </amendment>
   <heading>some heading text</heading>
   <newwrapper>
      <amendment chapter="1">
               <baz/>
         </amendment>
   </newwrapper>
</section>

説明:

属性xsl:for-each-groupとの適切な使用。group-adjacent


Ⅱ.XSLT 1.0 ソリューション:

<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="kFollowing" match="amendment[not(@chapter >2)]" use=
 "generate-id(preceding-sibling::*
                [not(self::amendment and @chapter &lt;= 2)][1])"/>

 <xsl:template match="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>


 <xsl:template match=
 "*[not(self::amendment and @chapter &lt;= 2)
  and
    following-sibling::*[1][self::amendment and not(@chapter >2)]
    ]">
  <xsl:call-template name="identity"/>
  <newwrapper>
   <xsl:apply-templates mode="inGroup"
                        select="key('kFollowing', generate-id())"/>
  </newwrapper>
 </xsl:template>

 <xsl:template match="*" mode="inGroup">
  <xsl:call-template name="identity"/>
 </xsl:template>
 <xsl:template match="amendment[not(@chapter >2)]"/>
</xsl:stylesheet>

この変換が同じ XML ドキュメント (上記) に適用されると、同じ正しい結果が生成されます。

説明:

以下の適切な使用:

  1. ID ルールの利用とオーバーライド。

  2. そのグループの直前の兄弟要素の関数として、属性が より大きくない隣接amendment要素のグループを定義するためのキー。chapter2generate-id()

于 2012-07-21T23:33:09.350 に答える
0

Dimitre Novatchev、属性を文字列に変更すると、xslt が機能します。ありがとう。

<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="kFollowing" match="amendment[(@chapter='1' or @chapter='2')]" use="generate-id(preceding-sibling::*[not(self::amendment and (@chapter='1' or @chapter='2'))][1])"/>
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[not(self::amendment and (@chapter='1' or @chapter='2')) and following-sibling::*[1][self::amendment and (@chapter='1' or @chapter='2')]]">
        <xsl:call-template name="identity"/>
        <newwrapper>
            <xsl:apply-templates mode="inGroup" select="key('kFollowing', generate-id())"/>
        </newwrapper>
    </xsl:template>
    <xsl:template match="*" mode="inGroup">
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="amendment[(@chapter='1' or @chapter='2')]"/>
</xsl:stylesheet>
于 2012-07-27T16:08:20.613 に答える