0

変換に使用するXSLTマップがあります。私の問題は、カウント1.eをどのように思い出すことができるかです。ループが実行された回数。例えば

<xsl: for each>  // This runs some 3 times

<xsl: call-template > // This call template recursively runs 10 times
<xsl: with- param >
</xsl: call-template >

<xsl: for each>

上記の例では、外側のforループが3回実行され、内側のcall-templateが再帰的に自分自身を呼び出して、10回と思われるものを出力します。したがって、全部で3 * 10=30サイクルです。

ここで必要なのは、最初の番号001があるとします。forループが最初に実行されると、テンプレートが呼び出され、10回再帰的に呼び出されます。だから私は001から010までの数字を印刷しました

次にループを実行するときに、3回目に001から010までの数値を再度出力しました。しかし、私が欲しいのは最後のカウントを覚えておくことです。最初の反復で010に達したとします。したがって、2回目の反復では、カウントを011から開始し、021まで印刷します。3回目は、022-032から印刷します。

しかし、誰かが私にそれをどのように行うことができるかを提案できますか?印刷がすでに行われた最後の値をどのように思い出すことができますか?

そしてもう1つ、実際にはXSLT1.0に制限されています。それが、上記の例のようにループしなければならない理由です。

これは大きな助けになるでしょう

私がやりたいのは次のようなものです。入力xmlが次のようになっているとします。

<A>

<B from="123456781" to="123456782">
........
</B>
<B from="123456781" to="123456785">
........
</B>
<B from="123456788" to="123456788">
........
</B>

</A>

上記のxmlでは、各ノードBは「from-to」の範囲に関連付けられています。指定された範囲内の数と同じ数のouputBノードを作成する必要があります。また、作成された各outputBノードの一意のカウントを取得する必要があります。たとえば、出力xmlは次のようになります。

<root>

<outputB value="123456781" id="001"> // from first B node from="123456781" to="123456782"
<outputB value="123456782" id="002">

<outputB value="123456781" id="003">
<outputB value="123456782" id="004">// from second B node from="123456781" to="123456785"
<outputB value="123456783" id="005">
<outputB value="123456784" id="006">
<outputB value="123456785" id="007">

<outputB value="123456788" id="008">// from third B node from="123456788" to="123456788"

</root>

したがって、上記のxslでは、各入力Bノードでbu for-eachをロッピングしている間、fromおよびtoパラメーターの範囲値に基づいて再帰的にデータを入力しました。したがって、正確な数のoutputBノードを作成します。ただし、ここでの問題は、生成されたxmlで一意のカウントまたはIDを維持することです。

ありがとう :)

4

4 に答える 4

1

XSLT は関数型言語です。関数型言語では物事を「思い出す」ことはできません。時間の概念はなく、過去の記憶もありません。入力の何かの関数として、出力のすべてを計算する必要があります。

于 2012-07-03T12:05:13.357 に答える
0

非常に特殊な状況を除いて、XSLTの値を覚えていないか、または進むにつれて合計することさえありません。ただし、一般的には、そうする必要はありません。

だからあなたが持っているなら:

<xsl:for-each select="conditiona">  // This runs some 3 times

次に、カウントを提供するために必要なすべてがあります。

<xsl:value-of select="count(conditiona)"/> // this displays 3
于 2012-07-03T10:00:23.107 に答える
0

どう?このXMLPlaygroundで実行できます(出力ソースを参照)。for-eachを完全に回避します(XSLTでは常に回避するのが最適です)。

ここには2つの重要な概念があります。

  1. その範囲が必要とする限り、同じノードで繰り返しテンプレートマッチング
  2. ルートマッチングテンプレートをすべてのBノードに適用するのではなく、ノードに次の兄弟のプロセスを開始させる。このように、「どこで起きたの?」関係は、渡されたパラメータを介して維持できます。これは非正統的ですが、機能します。

コード:

<!-- root - kick things off, for each B node -->
<xsl:template match="/">
    <xsl:apply-templates select='//B[1]' />
</xsl:template>

<!-- iteration content - B nodes -->
<xsl:template match='B'>

    <!-- recursion params -->
    <xsl:param name='index' select='@from' />
    <xsl:param name='id' select='position()' />
    <xsl:param name='pos' select='position()' />

    <!-- output node -->
    <outputB value='{$index}' id='{$id}' />

    <!-- now recurse for... -->
    <xsl:choose>

        <!-- ...as range requires -->
        <xsl:when test='(@from and @to) and (not($index) or $index &lt; @to)'>
            <xsl:apply-templates select='.'>
                <xsl:with-param name='index' select='$index + 1' />
                <xsl:with-param name='id' select='$id + 1' />
            </xsl:apply-templates>
        </xsl:when>

        <!-- ...next B node, if there is one -->
        <xsl:when test='following-sibling::B'>
            <xsl:apply-templates select='following-sibling::B[1]'>
                <xsl:with-param name='id' select='$id + 1' />
            </xsl:apply-templates>
        </xsl:when>
    </xsl:choose>

</xsl:template>

出力:

<outputBs value="123456781" id="1"/>
<outputBs value="123456782" id="2"/>
<outputBs value="123456783" id="3"/>
<outputBs value="123456781" id="4"/>
<outputBs value="123456782" id="5"/>
<outputBs value="123456783" id="6"/>
<outputBs value="123456784" id="7"/>
<outputBs value="123456785" id="8"/>
<outputBs value="123456788" id="9"/>
于 2012-07-03T11:05:51.103 に答える
0

テンプレートを呼び出すときは、「深さ」のパラメーターを渡すだけです。

 <xsl:template Name="x">
   <xsl:param name="depth">

   <xsl:call-template name="x">
     <xsl:with param name="depth" select=="depth+1" />
   </xsl:call-template>
 </xsl:template>

次に、外側のループに対して同様のことを行います。このループをどのように行っているかは明確ではありませんが、position() を使用できる可能性があります。次に、必要な数は position()*10 + depth です。

于 2012-07-03T10:10:55.443 に答える