我有两个结构相似的 XML 文件。需要使用 XSLT 将这些 xml 文件合并为一个。
01.xml(有两个引用 REF01 和 REF10)
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<common-indicators>
<common-indicator>
<reference>REF01</reference>
<name>name1</name>
<reports>
<report>
<id>15</id>
<name>name15</name>
</report>
<report>
<id>16</id>
<name>name16</name>
</report>
</reports>
</common-indicator>
<common-indicator>
<reference>REF10</reference>
<name>name10</name>
<reports>
<report>
<id>30</id>
<name>name30</name>
</report>
<report>
<id>32</id>
<name>name32</name>
</report>
<report>
<id>34</id>
<name>name34</name>
</report>
</reports>
</common-indicator>
</common-indicators>
XSLT 转换(包括 xml 文件作为 param1 与两个引用 REF02 和 REF10 合并):
<xsl:param name="param1">
<common-indicators>
<common-indicator>
<reference>REF02</reference>
<name>name2</name>
<reports>
<report>
<id>17</id>
<name>name17</name>
</report>
<report>
<id>18</id>
<name>name18</name>
</report>
</reports>
</common-indicator>
<common-indicator>
<reference>REF10</reference>
<name>name10</name>
<reports>
<report>
<id>36</id>
<name>name36</name>
</report>
<report>
<id>38</id>
<name>name38</name>
</report>
<report>
<id>40</id>
<name>name40</name>
</report>
</reports>
</common-indicator>
</common-indicators>
</xsl:param>
<xsl:variable name="updateItems" select="$param1/common-indicators/common-indicator" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="common-indicators">
<xsl:copy>
<xsl:apply-templates select="common-indicator" />
<xsl:apply-templates select="$updateItems" />
</xsl:copy>
</xsl:template>
XSLT 3.0 引入了合并功能。
这是一个为您提供的概念示例。
List1.xml
<?xml version="1.0"?>
<list>
<item id="1">
<descr ref="a"/>
<descr ref="b"/>
</item>
<item id="2">
<descr ref="c"/>
<descr ref="d"/>
</item>
<item id="3">
<descr ref="e">one</descr>
<descr ref="f">one</descr>
</item>
</list>
List2.xml
<?xml version="1.0"?>
<list>
<item id="4">
<descr ref="z"/>
<descr ref="y"/>
</item>
</list>
XSLT 3.0
<?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"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<!--fully qualified path's spaces shall be encoded via encode-for-uri()-->
<!--directory and file names are case sensitive-->
<xsl:param name="directory" select="'c:/XSLT30/Merging two XML files_XSLT30'"/>
<xsl:param name="wildcard" select="'List*.xml'"/>
<!--<xsl:mode streamable="yes"/>-->
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="/">
<list>
<xsl:merge>
<xsl:merge-source for-each-item="collection('file:///' || encode-for-uri($directory) || '?strip-space=yes;select=' || $wildcard)"
select="list/item">
<xsl:merge-key select="@id"
order="ascending"/>
</xsl:merge-source>
<xsl:merge-action>
<xsl:sequence select="current-merge-group()"/>
</xsl:merge-action>
</xsl:merge>
</list>
</xsl:template>
</xsl:stylesheet>
输出
<?xml version="1.0" encoding="UTF-8"?>
<list>
<item id="1">
<descr ref="a"/>
<descr ref="b"/>
</item>
<item id="2">
<descr ref="c"/>
<descr ref="d"/>
</item>
<item id="3">
<descr ref="e">one</descr>
<descr ref="f">one</descr>
</item>
<item id="4">
<descr ref="z"/>
<descr ref="y"/>
</item>
</list>