使用XSLT为XML指定节点值及属性追加TEST的实现求助
XSLT实现方案
针对你的三个转换需求,我们可以基于XSLT的身份转换模板(默认复制所有节点和属性),仅对需要修改的部分编写针对性规则来实现:
核心思路
身份转换模板会原样复制XML中所有未被特殊模板匹配的内容,我们只需要为需要修改的节点/属性单独编写匹配逻辑,避免重复编写大量复制代码。
完整XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <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> <!-- 需求1:为指定Login节点下的Value追加"_TEST" --> <xsl:template match="cXML/Header/From/Login[@domain='RollID']/Value"> <xsl:copy> <xsl:value-of select="concat(., '_TEST')"/> </xsl:copy> </xsl:template> <!-- 需求2:为OrderHeaderID的orderID属性追加"_TEST";需求3:移除orderDate属性的"TEST-"前缀 --> <xsl:template match="OrderHeaderID"> <xsl:copy> <!-- 处理orderID属性 --> <xsl:if test="@orderID"> <xsl:attribute name="orderID"> <xsl:value-of select="concat(@orderID, '_TEST')"/> </xsl:attribute> </xsl:if> <!-- 处理orderDate属性 --> <xsl:if test="@orderDate"> <xsl:attribute name="orderDate"> <xsl:value-of select="substring-after(@orderDate, 'TEST-')"/> </xsl:attribute> </xsl:if> <!-- 保留OrderHeaderID的其他属性(如果存在) --> <xsl:apply-templates select="@*[not(local-name()='orderID' or local-name()='orderDate')]"/> <!-- 保留OrderHeaderID的子节点 --> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码细节说明
- 身份转换模板:作为基础逻辑,确保XML中不需要修改的部分完全保留原样,是XSLT批量修改场景的常用基础模板。
- 需求1的匹配模板:精准定位到
cXML/Header/From/Login[@domain='RollID']/Value节点,用concat()函数将原节点值与"_TEST"拼接后输出。 - 需求2&3的匹配模板:针对
OrderHeaderID元素做集中处理:- 对
orderID属性,直接用concat()追加后缀; - 对
orderDate属性,用substring-after()截取"TEST-"之后的内容(如果属性值没有该前缀,会直接返回原字符串); - 同时保留该元素的其他属性和子节点,避免丢失原有内容。
- 对
可选优化(XSLT 2.0+)
如果你使用的是XSLT 2.0及以上版本,处理orderDate时可以用正则替换,逻辑更直观:
<xsl:value-of select="replace(@orderDate, '^TEST-', '')"/>
内容的提问来源于stack exchange,提问作者Sunny2020
相关产品推荐
相关产品推荐

