6

このコード例では、B ノードの後、ノード C、D、E の前に B1 ノードを設定するという 2 つの課題があり、2 つ目の課題は、2 番目の KEY ノードを /ROOT/E/OTHER/DEAL/KEYS 構造に追加することです。

この XML サンプル:

        <ROOT>
          <A>some A text</A>
          <B>some B text</B>
          <C>some C text</C>
          <D>some D text</D>
          <E>
            <OTHER>
              <DEAL>
                <KEYS>
                  <KEY>
                    <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                    <KeyValue>123456|1</KeyValue>
                  </KEY>
                </KEYS>
              </DEAL>
            </OTHER>
          </E>
        </ROOT>

変換後:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:strip-space elements="*"/>
        <xsl:output method="xml" indent="yes"/>

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

        <!-- Identifiers are added by the system. Need to pass parms from the calling program -->
        <xsl:template match="ROOT" name="add-B1">
            <xsl:variable name="elements-after" select="C|D|E"/>
            <xsl:copy>
                <xsl:copy-of select="* except $elements-after"/>
                <B1>some B1 text</B1>
                <xsl:copy-of select="$elements-after"/>
            </xsl:copy>
        </xsl:template>

        <!-- KEY is added by the system. Need to pass parms from the calling program -->
        <xsl:template match="ROOT/E/OTHER/DEAL/KEYS" name="add-KEYS">
            <xsl:param name="KeyIdentifierTypeB">654321|1</xsl:param>
            <xsl:copy>
                <xsl:copy-of select="*"/>
                <KEY>
                    <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType>
                    <KeyValue>
                        <xsl:value-of select="$KeyIdentifierTypeB"/>
                    </KeyValue>
                </KEY>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>

なる:

        <?xml version="1.0" encoding="UTF-8"?>
        <ROOT>
            <A>some A text</A>
            <B>some B text</B>
            <B1 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">some B1 text</B1>
            <C>some C text</C>
            <D>some D text</D>
            <E>
                <OTHER>
                    <DEAL>
                        <KEYS>
                            <KEY>
                                <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                                <KeyValue>123456|1</KeyValue>
                            </KEY>
                        </KEYS>
                    </DEAL>
                </OTHER>
            </E>
        </ROOT>

2 番目のテンプレート定義が完全に無視されたのはなぜですか?

最初のコード カレッジが解決されました B1 ノードは、B ノードの後、ノード C、D、および E の前に設定されます。つまり、B1 ノードが設定され、その後に配置する必要があるノードは、C、D、および E です
。2 番目のテンプレート/ROOT/E/OTHER/DEAL/KEYS 構造に 2 番目の KEY ノードを追加するという 2 番目の課題の部分を満たす必要がある match="ROOT/E/OTHER/DEAL/KEYS" は、完全に無視されています。この事実に加えて、ROOT ノードで最初のテンプレート マッチをコメントすると、2 番目のテンプレート match="ROOT/E/OTHER/DEAL/KEYS" が正しく機能し、実際には追加のキーが追加されますが、最初のテンプレートの一致が常に 2 番目のテンプレートの一致を上書きする理由がわかりません。xsl:template match="ROOT/E/OTHER/DEAL/KEYS... および xsl:for-each select=... および xsl:call-template name="add-KEYS" を試します

私は実際に、apply-template がより高い構造を持つノード テンプレートを最も高い優先度で照合することを理解しています。XSLT ファイル内のテンプレートの場所を変更しても影響はありません。正確な行順序で読み取られるわけではなく、優先順位を一致させて処理します。一致するテンプレートごとに「apply-templates」を実行すると、XML 構造が変更され、暗黙のうちに「for-each」が作成されますが、構造が変更されたことを 2 番目のテンプレートに「アドバイス」する方法はわかりません。 、そしてなぜ私はそれをしなければならないのですか?2番目のテンプレートの一致は別のXPathの場所を探しているからです。私の場合、テンプレート シーケンスを適用する必要がありますか?...それを行うためのベスト プラクティスは何ですか?

期待される結果:

        <?xml version="1.0" encoding="UTF-8"?>
        <ROOT>
            <A>some A text</A>
            <B>some B text</B>
            <B1>some B1 text</B1>
            <C>some C text</C>
            <D>some D text</D>
            <E>
                <OTHER>
                    <DEAL>
                        <KEYS>
                            <KEY>
                                <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                                <KeyValue>123456|1</KeyValue>
                            </KEY>
                            <KEY>
                                <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType>
                                <KeyValue>654321|1</KeyValue>
                            </KEY>
                        </KEYS>
                    </DEAL>
                </OTHER>
            </E>
        </ROOT>
4

1 に答える 1

3

match="ROOT/E/OTHER/DEAL/KEYS"2 番目の課題の部分 (構造に 2 番目の KEY ノードを追加する) を満たす必要がある 2 番目のテンプレートは/ROOT/E/OTHER/DEAL/KEYS、完全に無視されています。

問題は、テンプレート マッチングROOTxsl:apply-templates. テンプレートは、xsl:apply-templates命令の結果として実行のために選択されるだけです。コードに がないxsl:apply-templatesため、XSLT プロセッサはテンプレートを適用せず、実行を終了します。

に置き換えるxsl:copy-ofとまた違ってきますxsl:apply-templates

これを行う方法は次のとおりです。

<xsl:stylesheet version="1.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()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <xsl:copy>
    <xsl:apply-templates select="@*|B/preceding-sibling::node()"/>
    <xsl:apply-templates select="B"/>
    <B1>some B1 text</B1>
    <xsl:apply-templates select="B/following-sibling::node()"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="KEY">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
   <KEY>
    <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType>
    <KeyValue>
     <xsl:value-of select="'654321|1'"/>
    </KeyValue>
   </KEY>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<ROOT>
    <A>some A text</A>
    <B>some B text</B>
    <C>some C text</C>
    <D>some D text</D>
    <E>
        <OTHER>
            <DEAL>
                <KEYS>
                    <KEY>
                        <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                        <KeyValue>123456|1</KeyValue>
                    </KEY>
                </KEYS>
            </DEAL>
        </OTHER>
    </E>
</ROOT>

必要な正しい結果が生成されます。

<ROOT>
   <A>some A text</A>
   <B>some B text</B>
   <B1>some B1 text</B1>
   <C>some C text</C>
   <D>some D text</D>
   <E>
      <OTHER>
         <DEAL>
            <KEYS>
               <KEY>
                  <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                  <KeyValue>123456|1</KeyValue>
                  <KEY>
                     <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType>
                     <KeyValue>654321|1</KeyValue>
                  </KEY>
               </KEY>
            </KEYS>
         </DEAL>
      </OTHER>
   </E>
</ROOT>
于 2012-08-24T12:27:02.183 に答える