基于子串匹配合并两个XML文件的XSLT实现问题
解决XML图片节点合并问题的完整方案
先明确示例输入文件
主数据XML(main.xml)
<annunci> <annuncio> <reference>333</reference> <images></images> </annuncio> <annuncio> <reference>444</reference> <images></images> </annuncio> </annunci>
图片数据XML(images.xml)
<images> <img> <url>https://example.com/img_333_1.jpg</url> <alt>Product 333 - Image 1</alt> </img> <img> <url>https://example.com/img_333_2.jpg</url> <alt>Product 333 - Image 2</alt> </img> <img> <url>https://example.com/img_444_1.jpg</url> <alt>Product 444 - Image 1</alt> </img> </images>
可用的XSLT代码
根据你使用的XSLT版本选择对应的代码:
XSLT 2.0+版本(推荐,语法更简洁)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 加载图片数据XML文件 --> <xsl:variable name="image-data" select="document('images.xml')"/> <!-- 复制整个主XML结构,除了需要替换的空images节点 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配空的images节点,替换为包含对应图片的节点 --> <xsl:template match="images[not(img)]"> <images> <!-- 获取当前商品的reference值 --> <xsl:variable name="current-ref" select="../reference"/> <!-- 筛选出url包含当前reference的img节点并复制 --> <xsl:copy-of select="$image-data//img[contains(url, $current-ref)]"/> </images> </xsl:template> </xsl:stylesheet>
XSLT 1.0版本(兼容旧版处理器)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:variable name="image-data" select="document('images.xml')"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="images[not(img)]"> <images> <xsl:variable name="current-ref" select="../reference"/> <!-- XSLT1.0不支持在copy-of里直接加条件,用for-each+if筛选 --> <xsl:for-each select="$image-data//img"> <xsl:if test="contains(url, $current-ref)"> <xsl:copy-of select="."/> </xsl:if> </xsl:for-each> </images> </xsl:template> </xsl:stylesheet>
关键注意事项
- 文件路径:
document('images.xml')里的路径要确保正确,如果两个文件不在同一目录,要写相对路径(比如../images/images.xml)或绝对路径。 - 匹配精度:如果需要更精确的匹配(比如避免把
3330和333混淆),可以修改contains的条件,比如用contains(url, concat('_', $current-ref, '_'))或者XSLT2.0+的正则匹配matches(url, concat('\b', $current-ref, '\b'))。 - 已有图片保留:当前模板只会替换空的
images节点,如果你的主XML里有部分annuncio已经有图片,不会被覆盖。如果需要强制替换所有images节点,把模板匹配规则改成match="images"即可。
最终输出示例
<annunci> <annuncio> <reference>333</reference> <images> <img> <url>https://example.com/img_333_1.jpg</url> <alt>Product 333 - Image 1</alt> </img> <img> <url>https://example.com/img_333_2.jpg</url> <alt>Product 333 - Image 2</alt> </img> </images> </annuncio> <annuncio> <reference>444</reference> <images> <img> <url>https://example.com/img_444_1.jpg</url> <alt>Product 444 - Image 1</alt> </img> </images> </annuncio> </annunci>
内容的提问来源于stack exchange,提问作者Ugo
相关产品推荐
相关产品推荐

