XSLT技术求助:移除子标签并按条件重命名父标签
XSLT转换问题修正
输入XML
<?xml version="1.0" encoding="UTF-8"?> <Payload> <a1>GDS</a1> <a2>82.0</a2> <tag0000> <array> <dateSent><string>20230130</string></dateSent> <timeSent><string>1259</string></timeSent> </array> </tag0000> </Payload>
转换需求
- 移除
<array>和<string>标签,直接保留其内部内容 - 标签重命名规则:
- 以
tag0开头的标签(如tag0000)→tagx+ 原标签第5位及以后字符(即tagx000) - 以
tag2开头的标签(如tag2000)→tagx+ 原标签第5位及以后字符(即tagx200)
- 以
- 最终输出需符合如下结构:
<?xml version="1.0" encoding="UTF-8"?> <Payload> <a1>GDS</a1> <a2>82.0</a2> <tagx000> <dateSent>20230130</dateSent> <timeSent>1259</timeSent> </tagx000> </Payload>
原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="string"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="*/text()[normalize-space()]"> <xsl:value-of select="normalize-space()"/> </xsl:template> <xsl:template match="*/text()[not(normalize-space())]" /> <xsl:template match="*[starts-with(name(), 'tag0') or starts-with(name(), 'tag2') ]"> <xsl:element name="{concat('tagx', substring(name(), 5))}"> <xsl:apply-templates select="*" /> </xsl:element> </xsl:template> <!-- rename item to its parent's name --> <xsl:template match="array"> <xsl:element name="{name(..)}"> <xsl:apply-templates/> </xsl:element> </xsl:template> </xsl:stylesheet>
问题现象
运行上述代码后,原标签(如<tag0000>)与重命名后的标签(如<tagx000>)同时存在,不符合需求。
修正后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 移除string标签,直接输出文本内容 --> <xsl:template match="string"> <xsl:value-of select="."/> </xsl:template> <!-- 恒等模板:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 清理无效空白文本节点 --> <xsl:template match="*/text()[normalize-space()]"> <xsl:value-of select="normalize-space()"/> </xsl:template> <xsl:template match="*/text()[not(normalize-space())]" /> <!-- 重命名tag0xxx和tag2xxx系列标签 --> <xsl:template match="*[starts-with(name(), 'tag0') or starts-with(name(), 'tag2')]"> <xsl:element name="{concat('tagx', substring(name(), 5))}"> <xsl:apply-templates select="@*|node()" /> </xsl:element> </xsl:template> <!-- 移除array标签,直接处理其子节点 --> <xsl:template match="array"> <xsl:apply-templates select="@*|node()"/> </xsl:template> </xsl:stylesheet>
修正说明
- 解决重复标签问题:原代码中处理
array的模板错误地重新创建了父标签(如tag0000),同时tag*的模板又生成了tagx*标签,导致两者共存。修正后直接移除<array>标签,将其内部节点直接传递给父标签的模板处理。 - 完善节点处理范围:原
tag*模板中仅处理子元素节点(select="*"),修正后改为处理所有子节点(select="@*|node()"),确保属性和文本都能被正确处理。 - 保留了原代码中清理空白文本、移除
<string>标签的功能,同时确保整体逻辑符合转换需求。
内容的提问来源于stack exchange,提问作者NainaR
相关产品推荐
相关产品推荐

