2017-12-05 6 views
0

コンテキスト変換ノード内の子ノードのID変換と述語の照合を使用して、特定の場所に新しいXML要素を追加しようとしています。私は正常に要素を追加することができますが、XMLの順序は重要で、私の現在のxslスクリプトは、テンプレートマッチングステートメントのコンテキストノード内に新しい要素を配置して、新しい要素を本質的に '順序外れ'兄弟ノードとして配置します。以下は、私のソースXMLです:条件付きで特定の兄弟ノードの後に​​新しいxml要素を追加する

<?xml version="1.0" encoding="utf-8"?> 
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"> 
    <CstmrCdtTrfInitn> 
     <PmtInf> 
     <CdtTrfTxInf> 
      <CdtrAgt> 
       <FinInstnId> 
        <Nm>Exciting Place</Nm> 
       </FinInstnId> 
       <BrnchId> 
        <Nm>Big Building</Nm> 
        <PstlAdr> 
        <Ctry>BR</Ctry> 
        </PstlAdr> 
       </BrnchId> 
      </CdtrAgt> 
      <Cdtr> 
       <Nm>/POP:Other</Nm> 
      </Cdtr> 
      <CdtrAcct> 
       <Id> 
        <IBAN>123456789123456789</IBAN> 
       </Id> 
       <Ccy>USD</Ccy> 
       <Nm>Winston Churchill</Nm> 
      </CdtrAcct> 
      <Tax> 
       <TaxId>100</TaxId> 
      </Tax> 
      <RmtInf> 
       <Ustrd>Test</Ustrd> 
      </RmtInf> 
     </CdtTrfTxInf> 
     </PmtInf> 
    </CstmrCdtTrfInitn> 
</Document> 

私は要素を追加する必要がある「パープ/ CD」XML文書に「CdtAgt/BrnchId/CTRY」兄弟ノードが値を持っている場合にのみ、「税」ノードを次"BR"。私は次のXSLスクリプトを試しましたが、要素を間違った場所に置きます。私は述語[]の一致ステートメントを運がなくても調整しようとしました。ここに私のスクリプトは次のとおりです。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xpath-default-namespace="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" 
    exclude-result-prefixes="xs xsl" 
    version="2.0"> 

    <xsl:output indent="yes"/> 

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

    <!-- Copy the children of the current node --> 
    <xsl:template name="copy-children"> 
     <xsl:copy-of select="./*"/> 
    </xsl:template> 

    <xsl:template match="*/CdtTrfTxInf[CdtrAgt/BrnchId/PstlAdr/Ctry[text() = 'BR']]"> 
     <xsl:copy> 

      <xsl:element name="Purp" namespace="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"> 
       <xsl:element name="Cd" namespace="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"> 
        <xsl:value-of select="'P1019'"/> 
       </xsl:element> 
      </xsl:element> 
      <xsl:call-template name="copy-children"/> 

     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

このスタイルシートは、「パープ/ CD」のノードがすぐに「CstmrCdtTrfInitn/PmtInf」ノードの代わりに、「税」ノード以下の目的の場所を追跡する不適切整列XMLドキュメントを生成します。以下、望ましくない出力:

<?xml version="1.0" encoding="UTF-8"?> 
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"> 
    <CstmrCdtTrfInitn> 
     <PmtInf> 
     <CdtTrfTxInf> 
      <Purp> 
       <Cd>P1019</Cd> 
      </Purp> 
      <CdtrAgt> 
       <FinInstnId> 
        <Nm>Exciting Place</Nm> 
       </FinInstnId> 
       <BrnchId> 
        <Nm>Big Building</Nm> 
        <PstlAdr> 
        <Ctry>BR</Ctry> 
        </PstlAdr> 
       </BrnchId> 
      </CdtrAgt> 
      <Cdtr> 
       <Nm>/POP:Other</Nm> 
      </Cdtr> 
      <CdtrAcct> 
       <Id> 
        <IBAN>123456789123456789</IBAN> 
       </Id> 
       <Ccy>USD</Ccy> 
       <Nm>Winston Churchill</Nm> 
      </CdtrAcct> 
      <Tax> 
       <TaxId>100</TaxId> 
      </Tax> 
      <RmtInf> 
       <Ustrd>Test</Ustrd> 
      </RmtInf> 
     </CdtTrfTxInf> 
     </PmtInf> 
    </CstmrCdtTrfInitn> 
</Document> 

私は新しいノードが「税」ノードの後に​​場所する必要がなく、コンテキストノード・レベルでの述語の一致を使用しながら、正しい結果を生成する方法がわかりません。これは私の問題だと思っていますが、スクリプトを調整する方法はわかりません。あなたの提案は非常に高く評価されています。その後

<?xml version="1.0" encoding="utf-8"?> 
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"> 
    <CstmrCdtTrfInitn> 
     <PmtInf> 
     <CdtTrfTxInf> 
      <CdtrAgt> 
       <FinInstnId> 
        <Nm>Exciting Place</Nm> 
       </FinInstnId> 
       <BrnchId> 
        <Nm>Big Building</Nm> 
        <PstlAdr> 
        <Ctry>BR</Ctry> 
        </PstlAdr> 
       </BrnchId> 
      </CdtrAgt> 
      <Cdtr> 
       <Nm>/POP:Other</Nm> 
      </Cdtr> 
      <CdtrAcct> 
       <Id> 
        <IBAN>123456789123456789</IBAN> 
       </Id> 
       <Ccy>USD</Ccy> 
       <Nm>Winston Churchill</Nm> 
      </CdtrAcct> 
      <Tax> 
       <TaxId>100</TaxId> 
      </Tax> 
      <Purp> 
       <Cd>P1019</Cd> 
      </Purp> 
      <RmtInf> 
       <Ustrd>Test</Ustrd> 
      </RmtInf> 
     </CdtTrfTxInf> 
     </PmtInf> 
    </CstmrCdtTrfInitn> 
</Document> 

答えて

1

あなたはTax要素の後に新しいノードを配置したい場合は、Tax要素に合わせてテンプレートを変更する必要がありますが....

<xsl:template match="CdtTrfTxInf[CdtrAgt/BrnchId/PstlAdr/Ctry[text() = 'BR']]/Tax"> 

以下の所望の出力この中でTaxノードを正確に(XSLT 2.0を使用しているのでxsl:next-matchを使用して)コピーし、その後に新しいノードを作成することができます。

このXSLTを試してみましょう。これは、デフォルトの名前空間を使用して新しい要素を出力することでもう少し簡略化しました。

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xpath-default-namespace="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" 
    xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" 
    exclude-result-prefixes="xs xsl" 
    version="2.0"> 

    <xsl:output indent="yes"/> 

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

    <xsl:template match="CdtTrfTxInf[CdtrAgt/BrnchId/PstlAdr/Ctry[text() = 'BR']]/Tax"> 
     <xsl:next-match /> 
     <Purp> 
      <Cd> 
       <xsl:text>P1019</xsl:text> 
      </Cd> 
     </Purp> 
    </xsl:template> 
</xsl:stylesheet> 
+0

これは、美しく動作します。常にシンプルなもの。助けてくれてありがとうTim。 –

関連する問題