1

この XSLT 2.0 テンプレートがあります。

<xsl:template match="footnote">
    <xsl:variable name = "string" select="./text()"/>
    <xsl:variable name = "bool">
        <xsl:choose>
            <xsl:when test="$string = preceding::footnote/text()">
                <xsl:text>false</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>true</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:if test="$bool = 'true'">
        <xsl:variable name="footnoteCount">
            <xsl:call-template name="getItemNumber">
                <xsl:with-param name="node" select="."/>
            </xsl:call-template>
        </xsl:variable>
    <!-- DO XSL-FO TRANSFORMATION STUFF-->
    </xsl:if> 
    <xsl:if test="$bool = 'false'">
        <xsl:variable name = "footnoteCount">
            <xsl:if test="$string = preceding::footnote/text()">
                <xsl:value-of select="preceding::footnote/$footnoteCount"/>
            </xsl:if>
        </xsl:variable>
        <!--DO XSL-FO TRANSFORMATION STUFF-->
    </xsl:if>
</xsl:template>

サンプル XML を編集しました。これを変換したい:

<footnote>Foo bar</footnote>
<footnote>Bar foo</footnote>
<footnote>Foo bar</footnote>
<footnote>Foo bar</footnote>
<footnote>Bar</footnote>
<footnote>Foo</footnote>

これに:

<footnote>Foo bar</footnote>
<footnote>Bar foo</footnote>
<footnote>Bar</footnote>
<footnote>Foo</footnote

そして、XSL-FO を使用してスタイルを設定します。このスタイリングの目的は、本文のテキストに$footnotecount、ページの下部にレンダリングされる脚注への番号付き参照 ( で表される) を含めることです。複製されたフットネートが 1 回だけレンダリングされ、番号参照 ( $footnoteCount) が複製ごとに同じになるように、ドキュメントを変換する必要があります。

したがって、このテンプレートでやろうとしていることは次のとおりです。

  1. 現在のノードのテキストを含む脚注要素が既に存在するかどうかを判断します。
  2. 存在しない場合 (つまり、'$bool' が 'true') は、前の脚注の番号を見つけ、それを増やし (これは 'getItemNumber' テンプレートで行われます)、'新しい' 脚注を作成します。存在する場合 ($bool が「false」)、テキストが一致するノードの $footnoteCount 変数を取得し、それを現在のノードに使用します。

私が問題を抱えているのは、脚注が既に存在するシナリオです。ノードが特定の基準を満たすかどうか (そのテキストが現在のノードの $string 変数と同じかどうか) に応じて、以前の特定のノードから $footnoteCount 変数を取得する方法がわかりません。$footnoteCount 変数は条件付きでのみ存在するという事実によって、さらに困難になっています (実際には、$bool は true または false のいずれかでなければならないため、常に存在する場合でも)。

ここで何をすべきかについて誰かアドバイスがありますか?

4

2 に答える 2

1

xsl:for-each-groupの使用に失敗するだけでなく、コードには他にも多くの問題があります。たとえば、次のようにします。

<xsl:variable name = "bool">
    <xsl:choose>
        <xsl:when test="$string = preceding::footnote/text()">
            <xsl:text>false</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>true</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

あなたはそれを次のように書くことができます

<xsl:variable name="bool" as="xs:boolean()" 
    select="$string = preceding::footnote"/>

次に、これを行います。

<xsl:if test="$bool = 'true'">
    <xsl:variable name="footnoteCount">
        <xsl:call-template name="getItemNumber">
            <xsl:with-param name="node" select="."/>
        </xsl:call-template>
    </xsl:variable>
</xsl:if>

これは完全に役に立たない:変数は宣言されるとすぐにスコープから外れるので、参照することはできません。

XSLTについて背景を読む必要がありますが、まだ理解していないアイデアがたくさんあります。

于 2012-12-11T10:40:08.217 に答える
1

これはグループ化の問題のように見えます。XSLT2.0 では、xsl:for-each-group要素を使用して個別の要素を取得できます。

<xsl:for-each-group select="footnote" group-by=".">

番号付けを行うには、別のアプローチが必要だと思います。まず、脚注の説明とそのインデックスの「ルックアップ」を保持する変数を作成できます

    <xsl:variable name="footnotes">
        <xsl:for-each-group select="//footnote" group-by=".">
            <footnote id="{position()}">
                <xsl:value-of select="."/>
            </footnote>
        </xsl:for-each-group>
    </xsl:variable>

これは、footnotes変数に次の要素が含まれていることを意味します

<footnote id="1">Foo bar</footnote>
<footnote id="2">Bar foo</footnote>
<footnote id="3">Bar</footnote>
<footnote id="4">Foo</footnote>

次に、既存の脚注要素を数値参照に置き換えるには、次のようなテンプレートを作成します

    <xsl:template match="footnote">
        <footnote>
            <xsl:value-of select="$footnotes/footnote[. = current()]/@id"/>
        </footnote>
    </xsl:template>  

次の XSLT を試してください

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:variable name="footnotes">
        <xsl:for-each-group select="//footnote" group-by=".">
            <footnote id="{position()}">
                <xsl:value-of select="."/>
            </footnote>
        </xsl:for-each-group>
    </xsl:variable>

    <xsl:template match="/*">
        <xsl:apply-templates select="footnote"/>

        Footnotes
        <xsl:copy-of select="$footnotes"/>
    </xsl:template>

    <xsl:template match="footnote">
        <footnote>
            <xsl:value-of select="$footnotes/footnote[. = current()]/@id"/>
        </footnote>
    </xsl:template>
</xsl:stylesheet>

サンプル XML (ルート要素を想定) に適用すると、次のように出力されます。

<footnote>1</footnote>
<footnote>2</footnote>
<footnote>1</footnote>
<footnote>1</footnote>
<footnote>3</footnote>
<footnote>4</footnote>

Footnotes
<footnote id="1">Foo bar</footnote>
<footnote id="2">Bar foo</footnote>
<footnote id="3">Bar</footnote>
<footnote id="4">Foo</footnote>
于 2012-12-11T08:54:18.393 に答える