4

XSLT の「キー」関数を使用して、値を抽出し、XML の特定の位置に追加しようとしています。しかし、私はそれを正しく理解していません。以下は、入力と XSLT です。

助けてください。

入力 XML:

<input  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xsi:noNamespaceSchemaLocation="nbA2.8.90.xsd">
            <info>User Info </info>
            <team>User Team </team>
            <nodeA id="test">
                <inodeAA> Sample </inodeAA>
                <inodeAB> Samples </inodeAB>
            </nodeA>
            <nodeA id="test2">
                <inodeAA> Sample </inodeAA>
                <inodeAB> Samples </inodeAB>
            </nodeA>
            <ns3:output xmlns:ns3="http://mysample.org">
                <ns3:reply id="test">
                    <ns3:pkey>55555</ns3:pkey>
                    <ns3:place>SampleLoc</ns3:place>
                </ns3:reply>
                <ns3:reply id="test2">
                    <ns3:pkey>55557</ns3:pkey>
                    <ns3:place>SampleLoc2</ns3:place>
                </ns3:reply>
            </ns3:output>
        </input>

期待される出力:

<input xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xsi:noNamespaceSchemaLocation="nbA2.8.90.xsd">
        <info>User Info </info>
        <team>User Team </team>
        <nodeA id="test">
            <inodeAA> Sample </inodeAA>
            <pkey>55555</pkey>
            <inodeAB> Samples </inodeAB>
        </nodeA>
        <nodeA id="test2">
            <inodeAA> Sample </inodeAA>
            <pkey>55557</pkey>
            <inodeAB> Samples </inodeAB>
        </nodeA>            
    </input>

以下は私のXSLです:

    <xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:ns3="http://mysample.org"
        exclude-result-prefixes="soap xsl">
        <xsl:output omit-xml-declaration="no" indent="yes" />

        <xsl:key name="parKey" match="ns3:output/ns3:reply/ns3:pkey" use="/input/ns3:output/ns3:reply/@id"></xsl:key>

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

        <xsl:template match="/input">
            <xsl:variable name="output_186" select="ns3:output"/>
            <xsl:copy>
                <xsl:copy-of copy-namespaces="no" select="./@*" />
                <xsl:copy-of select=" * except $output_186"></xsl:copy-of>
            </xsl:copy> 
        </xsl:template>

        <xsl:template match="/input//nodeA">
            <xsl:copy>
                <xsl:copy-of copy-namespaces="no" select="./@*" />
                <pkey>
                    <xsl:copy-of select="key('parKey', @id)|." />           
                </pkey>                 
                <xsl:copy-of copy-namespaces="no" select="node()" />
            </xsl:copy>             
        </xsl:template> 
    </xsl:stylesheet>

出力は次のとおりです。必須フィールドが表示されていません

    <input xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"        
        xsi:noNamespaceSchemaLocation="nbA2.8.90.xsd" >
        <info>User Info </info>
        <team>User Team </team>
        <nodeA id="test">
            <inodeAA> Sample </inodeAA>
            <inodeAB> Samples </inodeAB>
        </nodeA>
        <nodeA id="test2">
            <inodeAA> Sample </inodeAA>
            <inodeAB> Samples </inodeAB>
        </nodeA>
    </input>

正確に私が行方不明になっているところを助けてください。

ありがとう...

4

3 に答える 3

1

use属性xsl:keyは、一致する要素に相対的なパスであるため、おそらく次のようになります。

<xsl:key name="parKey" match="ns3:pkey" use="../@id"/>

親要素pkeyの属性によって要素をグループ化するため。idreply

しかし、より一般的には、/inputテンプレートは疑わしいものです。

    <xsl:template match="/input">
        <xsl:variable name="output_186" select="ns3:output"/>
        <xsl:copy>
            <xsl:copy-of copy-namespaces="no" select="./@*" />
            <xsl:copy-of select=" * except $output_186"></xsl:copy-of>
        </xsl:copy> 
    </xsl:template>

inputこれは、ソース要素全体(から)をコピーするだけであり、テンプレートを再帰的に適用するns3:outputことはないnodeAため、を処理するテンプレートが起動することはありませpkeyん。

次のようなものを試してください。

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:ns3="http://mysample.org"
    exclude-result-prefixes="xsl">
    <xsl:strip-space elements="*" />
    <xsl:output omit-xml-declaration="no" indent="yes" />

    <xsl:key name="parKey" match="ns3:pkey" use="../@id"/>

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

    <!-- except ns3:output -->
    <xsl:template match="ns3:output" />

    <xsl:template match="nodeA">
        <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="@*|node()" />
            <xsl:element name="pkey">
                <xsl:value-of select="key('parKey', @id)" />
            </xsl:element>
        </xsl:copy>             
    </xsl:template> 
</xsl:stylesheet>
于 2012-12-14T17:07:09.663 に答える
1

より短い解決策:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ns3="http://mysample.org">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:key name="kpKeyByParentId" match="ns3:pkey" use="../@id"/>

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

 <xsl:template match="inodeAA">
  <xsl:call-template name="identity"/>
  <xsl:apply-templates select="key('kpKeyByParentId', ../@id)"/>
 </xsl:template>

 <xsl:template match="ns3:pkey">
   <xsl:element name="{local-name()}">
    <xsl:apply-templates/>
   </xsl:element>
 </xsl:template>
 <xsl:template match="ns3:output"/>
</xsl:stylesheet>

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

<input  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xsi:noNamespaceSchemaLocation="nbA2.8.90.xsd">
    <info>User Info </info>
    <team>User Team </team>
    <nodeA id="test">
        <inodeAA> Sample </inodeAA>
        <inodeAB> Samples </inodeAB>
    </nodeA>
    <nodeA id="test2">
        <inodeAA> Sample </inodeAA>
        <inodeAB> Samples </inodeAB>
    </nodeA>
    <ns3:output xmlns:ns3="http://mysample.org">
        <ns3:reply id="test">
            <ns3:pkey>55555</ns3:pkey>
            <ns3:place>SampleLoc</ns3:place>
        </ns3:reply>
        <ns3:reply id="test2">
            <ns3:pkey>55557</ns3:pkey>
            <ns3:place>SampleLoc2</ns3:place>
        </ns3:reply>
    </ns3:output>
</input>

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

<input xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="nbA2.8.90.xsd">
   <info>User Info </info>
   <team>User Team </team>
   <nodeA id="test">
      <inodeAA> Sample </inodeAA>
      <pkey>55555</pkey>
      <inodeAB> Samples </inodeAB>
   </nodeA>
   <nodeA id="test2">
      <inodeAA> Sample </inodeAA>
      <pkey>55557</pkey>
      <inodeAB> Samples </inodeAB>
   </nodeA>
</input>

説明:

  1. アイデンティティ ルールは、実行のために選択されたすべてのノードを「そのまま」コピーします。

  2. 一致する ovveriding テンプレートinodeAAは、アイデンティティ テンプレートを呼び出して自分自身をコピーし、親の属性がこの親の属性と同じ値を持つ任意のns3:pkey要素にテンプレートを適用します。利便性と効率のために、これはキーを参照する関数を呼び出すことによって行われます。この関数は、をその親の属性の関数として定義します。ididinodeAAkey()"kpKeyByParentId"ns3:pkeyid

  3. 要素に一致するテンプレートns3:pkeyは、名前が一致した要素のローカル名である要素を (名前空間なしで) 作成し、その内容もコピーします。

  4. 要素ns3:outputとそのサブツリー全体が、空の本体を持つ一致するテンプレートによって処理から除外 (「削除」) されます。

于 2012-12-14T18:54:27.073 に答える