基于节点值修改XML标签的问题及XSLT调试需求
问题:根据name节点末尾数字修改标签名
原始XML内容
<loadUnit> <suspect>false</suspect> <attributeValue> <name>Lottable02</name> </attributeValue> <attributeValue> <name>Lottable07</name> <value>SLSIT0611-2</value> </attributeValue> <attributeValue> <name>Lottable10</name> <value>LA2</value> </attributeValue> <loadUnit>
需求说明
需要根据<name>节点文本末尾的数值,修改对应<attributeValue>内的<name>和<value>标签名。例如:
输入:
<attributeValue> <name>Lottable07</name> <value>SLSIT0611-2</value> </attributeValue>
输出:
<attributeValue> <name7>Lottable07</name7> <value7>SLSIT0611-2</value7> </attributeValue>
此前尝试的问题
1. 字符串替换方案
尝试直接用字符串替换:
replacedbody = replacedbody.replaceFirst("(?s)<name>", "<name7>"); replacedbody = replacedbody.replaceFirst("(?s)</name>", "</name7>"); replacedbody = replacedbody.replaceFirst("(?s)<value>", "<value7>"); replacedbody = replacedbody.replaceFirst("(?s)</value>", "</value7>");
但当<attributeValue>中没有<value>节点时,会出现匹配错误的问题。
2. XSLT方案问题
编写的XSLT生成的标签后缀是24、26这类非预期数字,而非<name>末尾的目标数字:
错误输出示例:
<attributeValue> <name24>Lottable01</name24> <value24/> </attributeValue> <attributeValue> <name26>Lottable02</name26> <value26>LOT-02</value26> </attributeValue> <attributeValue> <name28>Lottable03</name28> <value28>LOT-03</value28> </attributeValue>
所用XSLT代码:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="attributeValue[name[substring(., string-length() - 1, string-length())]]"> <xsl:variable name="position" select="position()"/> <attributeValue> <xsl:element name="name{$position}"> <xsl:value-of select="name"/> </xsl:element> <xsl:element name="value{$position}"> <xsl:value-of select="value"/> </xsl:element> </attributeValue> </xsl:template> </xsl:stylesheet>
正确的XSLT实现方案
核心是提取<name>文本末尾的数字,而非使用position()(该方法会统计所有节点,导致后缀数值异常)。
修改后的XSLT:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 身份模板:复制所有未匹配的节点,保留原始结构 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配并处理attributeValue节点 --> <xsl:template match="attributeValue"> <attributeValue> <!-- 提取name文本末尾的数字,处理前导零情况 --> <xsl:variable name="nameText" select="name"/> <xsl:variable name="finalSuffix"> <xsl:choose> <!-- 处理末尾两位是0X的情况,提取X作为后缀 --> <xsl:when test="substring($nameText, string-length($nameText)-1, 1) = '0'"> <xsl:value-of select="substring($nameText, string-length($nameText))"/> </xsl:when> <!-- 处理末尾两位是非零开头的数字,直接提取两位 --> <xsl:otherwise> <xsl:value-of select="substring($nameText, string-length($nameText)-1)"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <!-- 生成带后缀的name标签 --> <xsl:element name="name{$finalSuffix}"> <xsl:value-of select="$nameText"/> </xsl:element> <!-- 仅当存在value节点时,生成带后缀的value标签 --> <xsl:if test="value"> <xsl:element name="value{$finalSuffix}"> <xsl:value-of select="value"/> </xsl:element> </xsl:if> </attributeValue> </xsl:template> </xsl:stylesheet>
方案说明
- 精准提取
<name>文本末尾的数字,自动处理前导零(如Lottable07提取7,Lottable10提取10) - 仅在
<attributeValue>包含<value>节点时才生成对应的valueXX标签,避免空标签 - 保留原始XML中其他节点(如
<suspect>)的结构不变
内容的提问来源于stack exchange,提问作者keku keku
相关产品推荐
相关产品推荐

