XSLT作为XML转换的核心技术,提供了原生的文档合并能力,不需要额外依赖其他工具,就能将多个独立的XML文档整合为一份结构统一的文档,满足数据汇总、内容拼接等需求。

XSLT合并文档的核心原理
XSLT合并文档的核心是使用document()函数,该函数可以加载外部的XML文档,将其解析为节点树,之后通过XPath表达式提取需要的节点,再插入到当前转换输出的文档中。整个流程不需要手动解析XML,XSLT引擎会自动处理文档的加载和节点映射。
基础合并示例:合并两个简单XML文档
首先准备两个待合并的源XML文档,第一个是员工基础信息文档employees.xml:
<?xml version="1.0" encoding="UTF-8"?>
<employees>
<employee id="1">
<name>张三</name>
<age>28</age>
</employee>
<employee id="2">
<name>李四</name>
<age>32</age>
</employee>
</employees>
第二个是员工薪资信息文档salaries.xml:
<?xml version="1.0" encoding="UTF-8"?>
<salaries>
<salary employeeId="1">
<amount>8000</amount>
<level>P5</level>
</salary>
<salary employeeId="2">
<amount>12000</amount>
<level>P6</level>
</salary>
</salaries>
接下来编写XSLT样式表,将两个文档合并为包含员工完整信息的文档:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 输出格式为XML -->
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<!-- 匹配根节点,生成合并后的根元素 -->
<xsl:template match="/">
<merged_employees>
<!-- 遍历第一个文档的员工节点 -->
<xsl:for-each select="document('employees.xml')/employees/employee">
<xsl:variable name="empId" select="@id"/>
<employee>
<!-- 复制基础信息 -->
<xsl:copy-of select="name"/>
<xsl:copy-of select="age"/>
<!-- 从第二个文档匹配对应员工的薪资信息 -->
<xsl:copy-of select="document('salaries.xml')/salaries/salary[@employeeId=$empId]/*"/>
</employee>
</xsl:for-each>
</merged_employees>
</xsl:template>
</xsl:stylesheet>
转换后的输出文档如下:
<?xml version="1.0" encoding="UTF-8"?>
<merged_employees>
<employee>
<name>张三</name>
<age>28</age>
<amount>8000</amount>
<level>P5</level>
</employee>
<employee>
<name>李四</name>
<age>32</age>
<amount>12000</amount>
<level>P6</level>
</employee>
</merged_employees>
多文档批量合并的实现
如果需要合并同一目录下的多个XML文档,不需要逐个指定文件名,可以通过定义文档列表来实现批量合并。例如目录下有doc1.xml、doc2.xml、doc3.xml三个结构相同的文档,合并样式表可以这样编写:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<!-- 定义待合并的文档列表 -->
<xsl:variable name="docList">
<doc>doc1.xml</doc>
<doc>doc2.xml</doc>
<doc>doc3.xml</doc>
</xsl:variable>
<xsl:template match="/">
<all_docs>
<!-- 遍历文档列表,逐个加载合并 -->
<xsl:for-each select="msxsl:node-set($docList)/doc" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:variable name="docPath" select="text()"/>
<xsl:copy-of select="document($docPath)/*"/>
</xsl:for-each>
</all_docs>
</xsl:template>
</xsl:stylesheet>
这里使用了msxsl:node-set扩展函数将变量转换为节点集,方便遍历,不同XSLT处理器可能有对应的扩展函数,也可以直接通过外部参数传入文档路径列表。
合并过程中的注意事项
- 路径问题:
document()函数的路径是相对于XSLT样式表的位置,或者相对于当前XML文档的位置,需要根据实际部署情况调整路径写法。 - 命名空间冲突:如果待合并的文档带有不同的XML命名空间,合并后需要统一处理命名空间,避免节点匹配失败。
- 节点重复:如果多个文档存在相同ID或者相同结构的节点,需要提前定义去重逻辑,避免合并后出现冗余数据。
- 错误处理:如果
document()加载的文档不存在,部分XSLT处理器会抛出异常,需要提前校验文档是否存在,或者添加容错逻辑。
常见场景扩展
除了基础的节点拼接,XSLT还可以实现更复杂的合并逻辑,比如按照指定节点排序后合并、只合并符合特定条件的节点、合并时修改节点的属性值等。核心都是先通过document()获取目标文档的节点树,再用XPath筛选和转换节点,最后输出到结果文档中。
XSLTXML文档合并document_function修改时间:2026-06-30 00:42:30