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