2

私のXHTML入力:

<h1 class="section">Text</h1>
<h2 class="section">More text</h2>

必要なXHTML出力:

<div class="section">
<h1 class="section">Text</h1>
<h2 class="section">More text</h2>
</div>

したがって、このgroup-adjacentアプローチは適切と思われます。h1以下のコードは、ノードで正しいことを行いますが、タグ自体を含むノードh2内の他のすべてを消去します。<body><body>

明らかに私は間違いを犯していますが、for-each-groupそれがどこにあるのかを理解するのに十分な専門家ではありません。

ありがとう。

<xsl:template match="xhtml:body"> 
    <xsl:for-each-group select="xhtml:h1|xhtml:h2" group-adjacent="@class"> 
        <xsl:choose>
            <xsl:when test="current-grouping-key()='section'">
                <xsl:element name="div">
                    <xsl:attribute name="class">
                        <xsl:value-of select="current-grouping-key()"/>
                    </xsl:attribute>
                    <xsl:apply-templates select="current-group()"/> 
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="." />    
            </xsl:otherwise>
        </xsl:choose>            
    </xsl:for-each-group>  
</xsl:template>

更新:私が理解していなかったのは、それはfor-each-group基本的に、ポイントするノードのフィルターとして機能するということです。したがって、すべてのサブノードを保持する場合は、元のコマンドにを含める必要がありますselect="*"。さらに、グループ化ルールでは、すべてのサブノードがグループに含まれるようにする必要があります。これはgroup-adjacent、その仕事に適したツールではないことを意味します。group-starting-withは。

以下のテンプレート<body>は、XHTMLファイル全体を。で始まるグループに分割しますh1。(注意:このグループ化ルールは、anh1が常に<body>XHTMLの最初のサブノードであるという仮定に依存しています。)次に、条件を使用してグループをループし、各グループの最初の2つのノードを調べて一致するかどうかを確認します。私の基準。もしそうなら、私はそれらを私ので包みます<div>

私がやったことは基本的にXSLT内でPythonを書くことなので、もっと慣用的なXSLTソリューションがあるかどうかはまだ興味があります。

<xsl:template match="xhtml:body"> 
    <xsl:copy>            
    <!--Divide file into groups of nodes starting with h1 tags-->
    <xsl:for-each-group select="*" group-starting-with="xhtml:h1"> 
        <xsl:choose>
            <!-- if the group starts with h1.section + h2.section -->
            <xsl:when test="current-group()[1][@class='section'] and current-group()[2][name() = 'h2'] and current-group()[2][@class = 'section']">
                <!--wrap in a div tag-->
                <div class="section">
                    <xsl:apply-templates select="current-group()[1]"/>
                    <xsl:apply-templates select="current-group()[2]"/>
                </div>                    
                <!--then process the rest of the nodes in this group normally-->
                <xsl:apply-templates select="current-group()[position()>=3]"/> 
            </xsl:when>
            <xsl:otherwise>
                <!--process normally-->
                <xsl:apply-templates select="current-group()"/> 
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each-group> 
    </xsl:copy>  
</xsl:template>
4

1 に答える 1

2

質問の更新で、回答の一部を特定しました。ただし、この種の問題はグループ隣接で解決することは可能です。通常のパターンは、グループとしてラップされる要素に対して「true」、その他の要素に対して「false」のグループ化キーを計算することです。したがって、コーディングパターンは次のとおりです。

<xsl:for-each-group select="*" group-adjacent="self::h1 or self::h2">
  <xsl:choose>
    <xsl:when test="current-grouping-key()">
      <div>
        <xsl:copy-of select="current-group()"/>
      </div>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="current-group()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:for-each-group>
于 2012-06-28T08:05:53.687 に答える