1

Is it possible to join two xml files based on a node value like SQL?

I have two xml files:

<MailPackage>
   <Mail>
      <id>1</id>
      <field_1>foo</field_1>
      ...
      <field_n>bar</field_n>
   </Mail>
   <Mail>
      <id>2</id>
      <field_1>... </field_1>
       ...
   </Mail>
   ....
</MailPackackage>

and

<Transaction_data>
   <Transaction>
     <id>1</id>
     <account_number>10 </account_number>
     ....
   </Transaction>
   <Transaction>
     <id>1</id>
     <account_number> 50 </account_number>
      ....
   </Transaction>
   <Transaction>
     <id>2</id>
     <account_number> 20 </account_number>
      ....
   </Transaction>
</Transaction_data>

Now I'd like to join the two xml files by the value of the 'id' node. The expected result is:

<MailPackage>
   <Mail>
      <id>1 </id>
      <field_1>foo </field_1>
      ...
      <field_n>bar </field_n>
      <Transaction_data>
         <Transaction>
            <Account_number>10</Account_number>
             ...
         </Transaction>
         <Transaction>
            <Account_number>50 </Account_number>
             ...
         </Transaction>
      </Transaction_data>
   </Mail>
   <Mail>
      <id> 2 </id>
      <Field_1> ...</Field_1>
       ...
      <Transactions>
         <Transaction>
            <Account_number> 20 </Account_number>
             ....
         </Transaction>
      </Transactions>

   </Mail>
</MailPackage>

Can you guys give some help, how to begin?

4

1 に答える 1

1

要素をIDで <xsl:key>グループ化するように定義してから、メインファイルの適切な場所に要素を挿入できます。この記事では、セカンダリドキュメントからキーに一致するノードを選択するためのトリックについて説明します。XSLT2.0を使用している場合、このトリックは必要ありません。関数の3つの引数形式を使用するだけです。Transaction<xsl:for-each>key()

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

  <xsl:key name="trans" match="Transaction" use="id" />

  <!-- Identity template to copy everything we don't specifically override -->
  <xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
  </xsl:template>

  <!-- override for Mail elements -->
  <xsl:template match="Mail">
    <xsl:copy>
      <!-- copy all children as normal -->
      <xsl:apply-templates select="@*|node()" />
      <xsl:variable name="myId" select="id" />
      <Transaction_data>
        <xsl:for-each select="document('transactions.xml')">
          <!-- process all transactions with the right ID -->
          <xsl:apply-templates select="key('trans', $myId)" />
        </xsl:for-each>
      </Transaction_data>
    </xsl:copy>
  </xsl:template>

  <!-- omit the id element when copying a Transaction -->
  <xsl:template match="Transaction/id" />
</xsl:stylesheet>

<MailPackage>ドキュメントをメインの入力ドキュメントとして処理し、スタイルシートはトランザクションドキュメントを内部で参照します。

Mailこれはすべて、要素がすべて一意のIDを持っていることを前提としています。

于 2012-10-24T13:19:39.837 に答える