使用xslt连接基于节点文本的两个xml文件 [英] Join two xml files based on node text with xslt

查看:84
本文介绍了使用xslt连接基于节点文本的两个xml文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以基于像SQL这样的节点值来连接两个xml文件?

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

我有两个xml文件:

<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>

<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>

现在,我想通过"id"节点的值来连接两个xml文件.预期结果是:

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?

推荐答案

您可以定义<xsl:key>以按ID对Transaction元素进行分组,然后将其插入主文件中的适当位置. 本文介绍了使用<xsl:for-each>选择匹配节点的技巧辅助文档中的密钥-如果您具有XSLT 2.0,则不需要此技巧,只需使用key()函数的三参数形式即可.

You can define an <xsl:key> to group the Transaction elements by ID, then insert them at the appropriate places in the main file. This article explains a trick using <xsl:for-each> to select nodes matching a key from a secondary document - if you have XSLT 2.0 you don't need this trick, just use the three-argument form of the key() function.

<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>文档作为主要输入文档进行处理,而样式表在内部引用了交易文档.

You would process the <MailPackage> document as the main input document, and the stylesheet references the transactions document internally.

这全部假设您的Mail元素都具有唯一的ID.

This all assumes that your Mail elements all have unique IDs.

这篇关于使用xslt连接基于节点文本的两个xml文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆