3

処理中に結果ドキュメントにアクセスできるかどうか疑問に思います。

私が尋ねる理由は、入力ドキュメントを変換していて、いくつかの条件に応じて要素を挿入したいのですが、これはツリーをトラバースして作成がほぼ終了したときに発生する必要があります。

変換されたxmlは次のようになります。

<xform>
    <xforms>
        <model>
            <instance>
                <data />
                <data />
            </instance>
        </model>
        <bind />
        <bind />
        <bind />
    </xforms>
</xform>

<instance>変換中(上記のxmlがシリアル化される前)に、タグにアクセスして追加<data>の要素を挿入するつもりです。

入力ドキュメントは上記のxmlとは異なります。上記のxmlは、変換によって生成されるものです。

同様に、要素にアクセスして追加のノード<xform>を挿入したいと思います。<bind>

したがって、最終的なドキュメントは次のようになります(2つのデータノードと2つのバインドノードを追加したと仮定します)。

<xform>
    <xforms>
        <model>
            <instance>
                <data />
                <data />
                <data>new data node</data>
                <data>second new data node</data>
            </instance>
        </model>
        <bind />
        <bind />
        <bind />
        <bind>new bind node</bind>
        <bind>second new bind node</bind>
    </xforms>
</xform>

どんな助けでも大歓迎です。

4

2 に答える 2

3

いいえ、結果ドキュメントにアクセスすることはできませんが、変数に一時ツリーを作成し、必要に応じて別のモードのテンプレートを使用してそれらを再度処理することはできます。だから例えばの代わりに

<xsl:template match="/">
  <xsl:result-document href="example.xml">
<xform>
 <xforms>
  <model>
   <instance>
    <data>
    </data>
   </instance>
  </model>
  <bind />
  <bind />
  <bind />
 </xforms>
</xform>
  </xsl:result-document>
</xsl:template>

変数で最初の結果を作成してから、たとえば次のようにさらに処理します。

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

<xsl:template match="/">
  <xsl:variable name="temp1">
<xform>
 <xforms>
  <model>
   <instance>
    <data>
    </data>
   </instance>
  </model>
  <bind />
  <bind />
  <bind />
 </xforms>
</xform>
</xsl:variable>
  <xsl:result-document href="example.xml">
    <xsl:apply-templates select="$temp1/*"/>
  </xsl:result-document>
</xsl:template>

<xsl:template match="instance">
  <xsl:copy>
    <xsl:apply-templates/>
    <data>...</data>
  </xsl:copy>
</xsl:template>

そのサンプルはモードを使用していませんが、変数やさまざまな処理ステップでモードを使用して、各ステップのテンプレートを他のステップから明確に分離することがよくあります。

于 2012-05-22T12:30:10.557 に答える
1

はい、これを行う方法はマルチパス処理を使用することです。

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

 <xsl:template match="node()|@*" mode="#default pass2">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*" mode="#current"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
  <xsl:variable name="vPass1">
    <xsl:apply-templates/>
  </xsl:variable>

  <xsl:apply-templates select="$vPass1/node()" mode="pass2"/>
 </xsl:template>

 <xsl:template match="instance" mode="pass2">
  <instance>
    <xsl:apply-templates mode="pass2"/>
    <data>2</data>
    <data>3</data>
  </instance>
 </xsl:template>

 <xsl:template match="model" mode="pass2">
  <model>
   <xsl:apply-templates mode="pass2"/>
   <bind>1</bind>
   <bind>2</bind>
   <bind>3</bind>
  </model>
 </xsl:template>
</xsl:stylesheet>

この変換が提供されたXMLドキュメントに適用される場合:

<xform>
    <xforms>
        <model>
            <instance>
                <data>
                </data>
            </instance>
        </model>
        <bind />
        <bind />
        <bind />
    </xforms>
</xform>

IDルールを使用してそれ自体に変換し、この最初のパスの結果を変数にキャプチャします$vPass1。次に、2番目のパスで現在の結果が処理され、要素の下に$vPass12つの新しいdata子が追加され、要素の下にinstance3つの子が追加されます。したがって、最終的な結果は次のようになります。bindmodel

<xform>
   <xforms>
      <model>
         <instance>
            <data/>
            <data>2</data>
            <data>3</data>
         </instance>
         <bind>1</bind>
         <bind>2</bind>
         <bind>3</bind>
      </model>
      <bind/>
      <bind/>
      <bind/>
   </xforms>
</xform>
于 2012-05-22T12:27:31.910 に答える