如何使用XSLT将外部变量中的XML合并至主XML?
XSLT合并外部变量XML到指定节点方案
场景说明
将存储在外部变量中的XML内容,插入到主XML的<aggregatedd>节点内部,保留主XML其余结构不变。
示例文件
主XML
<mainRoot> <someNode>主节点内容</someNode> <aggregatedd> <!-- 目标插入位置 --> </aggregatedd> <anotherNode>其他数据</anotherNode> </mainRoot>
外部变量中的XML内容(字符串形式)
<externalItems> <item id="1">外部条目1</item> <item id="2">外部条目2</item> </externalItems>
常见错误XSLT(问题:未将字符串XML解析为节点)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="externalXml" select="'<externalItems><item id="1">外部条目1</item></externalItems>'"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="aggregatedd"> <xsl:copy> <!-- 错误:直接输出字符串,无法解析为XML节点 --> <xsl:value-of select="$externalXml"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
正确实现方案
方案1:XSLT 1.0(需扩展函数支持)
大部分主流处理器(如Xalan、Saxon)支持EXSLT扩展,可将字符串XML转为节点集:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"> <!-- 外部XML字符串参数 --> <xsl:param name="externalXml" select="'<externalItems><item id="1">外部条目1</item><item id="2">外部条目2</item></externalItems>'"/> <!-- 身份模板:复制主XML原有结构 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理aggregatedd节点,插入外部XML --> <xsl:template match="aggregatedd"> <xsl:copy> <!-- 将字符串XML转为节点集,插入到目标节点 --> <xsl:apply-templates select="exsl:node-set($externalXml)/node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
方案2:XSLT 2.0+(原生支持字符串转XML)
XSLT 2.0及以上版本提供parse-xml()函数,无需扩展即可处理:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 外部XML字符串参数 --> <xsl:param name="externalXml" select="'<externalItems><item id="1">外部条目1</item><item id="2">外部条目2</item></externalItems>'"/> <!-- 身份模板 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="aggregatedd"> <xsl:copy> <!-- 直接解析字符串为XML节点并插入 --> <xsl:apply-templates select="parse-xml($externalXml)/node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
方案3:外部变量为节点集时的简化处理
如果外部变量由处理器直接传入节点集(而非字符串),可直接引用:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 外部XML节点集参数 --> <xsl:param name="externalXmlNodeSet"/> <!-- 身份模板 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="aggregatedd"> <xsl:copy> <!-- 直接插入节点集内容 --> <xsl:apply-templates select="$externalXmlNodeSet/node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键注意点
- 身份模板是基础,确保主XML除目标节点外的结构完全保留。
- 若需保留
<aggregatedd>原有内容,可在插入外部XML前添加<xsl:apply-templates select="@*|node()"/>。 - 不同XSLT版本的处理逻辑差异需匹配所用处理器的支持版本。
内容的提问来源于stack exchange,提问作者Arthi Velloori
相关产品推荐
相关产品推荐

