如何将含不同子元素的两个XML文件按code字段合并为单个XML文件
按
<code>字段合并两个XML文件的实现方案 问题描述
现有两个XML文件,二者以<code>为共同匹配字段,需将它们的记录合并——合并后的单个<record>元素需包含两个源文件的所有对应数据,按<code>值分组。
源XML文件
XML 1
<?xml version="1.0" encoding="utf-8"?> <objects> <object> <record> <organization>1010</organization> <code>000010001</code> <name>A & SOLICITORS</name> <address_1>NORTH</address_1> <address_2/> <city/> <postcode>NUHMAN 1</postcode> <state/> <country>IE</country> <vat_number/> <telephone_number>054456849</telephone_number> <fax_number>01 64964659</fax_number> <currency>USD</currency> <start_date>1990-01-01</start_date> <end_date>2999-12-31</end_date> <status>ACTIVE</status> </record> <record> <organization>1010</organization> <code>0000100004</code> <name>ACCUTRON LTD.</name> <address_1>RAZIK PARK</address_1> <address_2/> <city>LIME</city> <postcode>V94654X7</postcode> <state/> <country>IE</country> <vat_number>IE6566750H</vat_number> <telephone_number>353 -61 - 54614</telephone_number> <fax_number/> <currency>USD</currency> <start_date>1990-01-01</start_date> <end_date>2999-12-31</end_date> <status>ACTIVE</status> </record> </object> </objects>
XML 2
<?xml version="1.0" encoding="utf-8"?> <objects> <record> <po_number>45670369</po_number> <po_currency>USD</po_currency> <po_organization>1010</po_organization> <code>0000156001</code> <name>SOFTWAREONE INC</name> <capture_row_type>NONE</capture_row_type> <source_system>SAP</source_system> </record> <record> <po_number>45670372</po_number> <po_currency>USD</po_currency> <po_organization>1010</po_organization> <code>0000156001</code> <name>SOFTWAREONE INC</name> <capture_row_type>NONE</capture_row_type> <source_system>SAP</source_system> </record> </objects>
期望合并结果示例
<?xml version="1.0" encoding="utf-8"?> <objects> <object> <record> <organization>1010</organization> <code>000010001</code> <name>A & SOLICITORS</name> <address_1>NORTH</address_1> <address_2/> <city/> <postcode>NUHMAN 1</postcode> <state/> <country>IE</country> <vat_number/> <telephone_number>054456849</telephone_number> <fax_number>01 64964659</fax_number> <currency>USD</currency> <start_date>1990-01-01</start_date> <end_date>2999-12-31</end_date> <status>ACTIVE</status> <po_number>45670369</po_number> <po_currency>USD</po_currency> <po_organization>1010</po_organization> <name>SOFTWAREONE INC</name> <capture_row_type>NONE</capture_row_type> <source_system>SAP</source_system> </record> <!-- 其他合并后的record省略 --> </object> </objects>
解决方案:使用XSLT 3.0实现合并
以下XSLT脚本可按<code>字段分组合并两个XML的记录,保留所有字段:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="UTF-8" indent="yes"/> <!-- 传入第二个XML文件的路径参数 --> <xsl:param name="xml2-path" select="'xml2.xml'"/> <xsl:variable name="xml2" select="document($xml2-path)"/> <!-- 收集两个XML中所有的record元素 --> <xsl:variable name="all-records" select="/objects/object/record | $xml2/objects/record"/> <!-- 按code值分组并合并 --> <xsl:template match="/"> <objects> <object> <xsl:for-each-group select="$all-records" group-by="code"> <record> <!-- 复制当前分组内所有record的子元素 --> <xsl:copy-of select="current-group()/*"/> </record> </xsl:for-each-group> </object> </objects> </xsl:template> </xsl:stylesheet>
使用步骤
- 将上述XSLT保存为
merge-xml.xsl - 将两个源XML文件(如命名为
xml1.xml、xml2.xml)与XSLT文件放在同一目录 - 使用支持XSLT 3.0的处理器(如Saxon)执行转换:
java -jar saxon-he-12.4.jar -s:xml1.xml -xsl:merge-xml.xsl -o:merged.xml
补充说明
- 若同一
<code>对应多条记录(如XML2中0000156001的两条记录),合并后的<record>会包含所有对应子元素 - 若某
<code>仅在一个XML中存在,合并后的<record>会保留该XML的所有字段,无缺失字段生成 - 若存在同名字段(如两个XML都有
<name>),合并后的<record>会保留所有同名元素,顺序与源文件中出现顺序一致
内容的提问来源于stack exchange,提问作者user20345501
相关产品推荐
相关产品推荐

