如何通过对比另一XML使用XSLT更新XML中price元素值
解决XML1中元素值更新为XML2对应值的问题
看起来你之前的模板之所以会新增<price>标签,是因为你可能在匹配<book>的模板里直接引入了XML2的<price>节点,而没有替换原有节点。咱们用身份转换模板来保留XML1的整体结构,同时精准替换<price>的值,这样就不会新增标签了。
核心思路
- 用身份模板复制XML1的所有节点和属性,只对
<price>元素做特殊处理; - 找到XML1中当前
<book>对应的XML2中的<book>节点(通过<publication>下的唯一标识,比如ISBN、ID等); - 替换原有
<price>的文本内容为XML2中的对应值,保持元素本身不变。
完整XSLT示例
假设你已经把XML2存储在变量$xml2中(如果是外部文件可以用document('xml2.xml')引入),下面是实现代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份模板:复制所有未被特殊匹配的节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 专门匹配XML1中的<price>元素,替换其值 --> <xsl:template match="book/price"> <!-- 获取当前book对应的publication唯一标识(这里用isbn,你可以换成实际的匹配键,比如id/title) --> <xsl:variable name="current-publication-id" select="../publication/isbn"/> <!-- 从XML2中找到对应publication的book节点下的price值 --> <xsl:variable name="updated-price" select="$xml2/books/book[publication/isbn = $current-publication-id]/price"/> <!-- 复制原price元素,替换内容为新值 --> <xsl:copy> <xsl:value-of select="$updated-price"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键说明
- 身份模板是XSLT中保留原文档结构的基础,它会复制所有没有被其他模板匹配的节点,这样我们只需要处理需要修改的
<price>元素即可; - 匹配
<publication>的唯一标识是关键:你需要确保$current-publication-id和XML2中的对应值完全一致,这样才能精准匹配到对应的<book>节点。如果你的<publication>用的是其他唯一标识(比如<id>),把代码中的isbn替换成对应的元素名就行; - 这个写法不会新增
<price>标签,而是直接修改原有<price>的内容,完美保留原XML1的结构。
示例验证
假设你的XML1片段是:
<books> <book> <publication> <isbn>978-1234567890</isbn> <title>XSLT Guide</title> </publication> <price>29.99</price> </book> </books>
XML2片段是:
<books> <book> <publication> <isbn>978-1234567890</isbn> <title>XSLT Guide</title> </publication> <price>34.99</price> </book> </books>
应用上面的XSLT后,输出的XML1会变成:
<books> <book> <publication> <isbn>978-1234567890</isbn> <title>XSLT Guide</title> </publication> <price>34.99</price> </book> </books>
内容的提问来源于stack exchange,提问作者Ironman
相关产品推荐
相关产品推荐

