如何用XSLT基于SKU匹配替换XML中的img元素
基于SKU匹配替换XML中的img元素
需求
通过外部XML文件(Extra-info.xml)匹配Input.xml中的元素:
- 基于SKU匹配Extra-info.xml里的img元素
- 若对应SKU存在img,则替换Input.xml中的原img元素,并添加所有匹配到的img
- 若对应SKU无img元素,则保留Input.xml中的原img
现有文件
Input.xml
<all> <item> <sku>3850950</sku> <name>Macbook Pro</name> <qty>3</qty> <img>original.jpg</img> </item> <item> <sku>3859955</sku> <name>iPhone 12</name> <qty>9</qty> <img>original-apple.jpg</img> </item> </all>
Extra-info.xml
<all> <additem> <sku>3850950</sku> <img>aaaaaaa</img> <img>bbbbbbb</img> </additem> <additem> <sku>3859955</sku> </additem> </all>
现有XSLT代码(仅能添加元素,无法替换)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:key name="group" match="additem" use="sku" /> <xsl:template match="item"> <xsl:copy> <xsl:copy-of select="*"/> <xsl:apply-templates select="key('group', sku, document('./extra-info.xml'))"/> </xsl:copy> </xsl:template> <xsl:template match="additem"> <xsl:for-each select="img"> <img> <xsl:value-of select="."/> </img> </xsl:for-each> </xsl:template> </xsl:stylesheet>
预期输出
<all> <item> <sku>3850950</sku> <name>Macbook Pro</name> <qty>3</qty> <img>aaaaaaa</img> <img>bbbbbbb</img> </item> <item> <sku>3859955</sku> <name>iPhone 12</name> <qty>9</qty> <img>original-apple.jpg</img> </item> </all>
修改后的XSLT代码(实现替换功能)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!-- 身份模板:复制所有未被自定义模板匹配的节点 --> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <!-- 定义外部XML的索引,按sku快速匹配additem节点 --> <xsl:key name="sku-match" match="additem" use="sku" /> <!-- 自定义匹配item下的img元素,实现替换逻辑 --> <xsl:template match="item/img"> <!-- 获取当前item对应的sku值 --> <xsl:variable name="current-sku" select="../sku/text()"/> <!-- 从外部XML中获取对应sku的所有img元素 --> <xsl:variable name="replacement-imgs" select="key('sku-match', $current-sku, document('./extra-info.xml'))/img"/> <!-- 判断是否有替换的img,有则输出所有替换项,无则保留原img --> <xsl:choose> <xsl:when test="$replacement-imgs"> <xsl:copy-of select="$replacement-imgs"/> </xsl:when> <xsl:otherwise> <xsl:copy-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
代码说明
- 身份模板:保留原有XML结构中未被自定义模板匹配的所有节点,保证sku、name、qty等其他元素正常复制。
- 索引定义:使用
<xsl:key>建立外部XML中additem节点与sku的关联,提升匹配效率。 - img替换逻辑:专门匹配
item下的img元素,通过变量获取当前item的sku值,利用索引从外部XML取出对应sku的所有img,再根据是否存在替换内容决定输出替换项还是保留原img。
内容的提问来源于stack exchange,提问作者Bohumír Masiar
相关产品推荐
相关产品推荐

