使用XSLT处理XML:修改元素值、新增缺失元素问题
解决XSLT修改指定Property元素及检查创建元素的问题
需求说明
- 修改XML中
name属性为1和2的Property元素的值,其余元素保持原样 - 检查
name属性为6的Property是否存在,若不存在则创建该元素
原XML文件
<?xml version="1.0" encoding="UTF-8"?> <Configuration name="abc"> <Properties> <Property name="1">A</Property> <Property name="2">B</Property> <Property name="3">C</Property> <Property name="4">D</Property> <Property name="5">E</Property> <Property name="6">F</Property> </Properties> </Configuration>
原XSLT代码的问题
原代码无法实现需求,核心问题包括:
- 模板匹配的
name属性值错误:需求是匹配name='1'和name='2',但原代码写的是'level'、'Workflow_level'等无关值,完全不匹配目标元素 Properties模板使用xsl:copy-of直接复制子元素,跳过了通用模板和自定义修改模板的执行,导致修改逻辑无法触发- 存在语法错误:
<xsl:stylesheet>标签未闭合,创建name=6的元素时,文本值abc未加引号,会被当作变量而非字符串 - 模板优先级冲突:自定义的
Properties模板覆盖了通用模板的处理,但未正确传递子元素的处理流程
修正后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.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> <!-- 修改name=1的Property元素的值 --> <xsl:template match="Property[@name='1']/text()"> <xsl:text>NEW_VALUE_1</xsl:text> </xsl:template> <!-- 修改name=2的Property元素的值 --> <xsl:template match="Property[@name='2']/text()"> <xsl:text>NEW_VALUE_2</xsl:text> </xsl:template> <!-- 处理Properties元素:确保name=6的元素存在 --> <xsl:template match="Properties"> <xsl:copy> <!-- 先处理所有子Property,触发上面的修改模板 --> <xsl:apply-templates select="Property" /> <!-- 检查是否存在name=6的Property,不存在则创建 --> <xsl:if test="not(Property[@name='6'])"> <Property name="6">DEFAULT_VALUE_6</Property> </xsl:if> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键修正点说明
- 修正模板匹配目标:将模板匹配改为
Property[@name='1']/text()和Property[@name='2']/text(),精准定位需要修改的元素文本内容 - 调整Properties处理逻辑:使用
xsl:apply-templates替代xsl:copy-of,让子Property元素能触发对应的修改模板,保证修改生效;同时通过xsl:if检查并创建缺失的name=6元素 - 修复语法错误:补全
<xsl:stylesheet>的命名空间和闭合标签,将创建元素的文本值改为带引号的字符串(示例中为DEFAULT_VALUE_6,可根据需求修改) - 保证模板执行流程:身份模板作为默认逻辑,自定义模板处理特定元素,优先级由匹配路径的特异性决定,确保修改和检查逻辑正常触发
内容的提问来源于stack exchange,提问作者anandkrishna sai
相关产品推荐
相关产品推荐

