使用xslt连接基于节点文本的两个xml文件 [英] Join two xml files based on node text with xslt
问题描述
是否可以基于像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屋!