如何使用XSLT 1.0转换XML中的多段指定文本内容
XSLT文本替换失效排查与修复
原始XML
<COMPANY> <SCHEDULES> <OFFICE name="BCO"> <DEPARTAMENT name="BCO1"> <days>monday:friday</days> <code>True</code> <indice>check</indice> </DEPARTAMENT> <TEAM name="BCO2"> <days>monday:friday</days> <code>True</code> <indice>check</indice> </TEAM> </OFFICE> <OFFICE name="RCO"> <DEPARTAMENT name="RCO1"> <days>monday:tuesday</days> <code>False</code> <indice>check</indice> </DEPARTAMENT> <TEAM name="RCO2"> <days>monday:wednesday</days> <code>True</code> <indice>check</indice> </TEAM> </OFFICE> <OFFICE name="LCO"> <DEPARTAMENT name="LCO1"> <days>wednesday:saturday</days> <code>True</code> <indice>check</indice> </DEPARTAMENT> <TEAM name="LCO2"> <days>wednesday:saturday</days> <code>True</code> <indice>check</indice> </TEAM> </OFFICE> <OFFICE name="ACO"> <DEPARTAMENT name="ACO1"> <days>monday</days> <code>False</code> <indice>check</indice> </DEPARTAMENT> <TEAM name="ACO2"> <days>tuesday</days> <code>False</code> <indice>check</indice> </TEAM> </OFFICE> </SCHEDULES> </COMPANY>
需求
将XML中所有文本节点的:
- "True" 替换为 "TRUE"
- "check" 替换为 "CHECK"
期望输出
<COMPANY> <SCHEDULES> <OFFICE name="BCO"> <DEPARTAMENT name="BCO1"> <days>monday:friday</days> <code>TRUE</code> <indice>CHECK</indice> </DEPARTAMENT> <TEAM name="BCO2"> <days>monday:friday</days> <code>TRUE</code> <indice>CHECK</indice> </TEAM> </OFFICE> <OFFICE name="RCO"> <DEPARTAMENT name="RCO1"> <days>monday:tuesday</days> <code>False</code> <indice>CHECK</indice> </DEPARTAMENT> <TEAM name="RCO2"> <days>monday:wednesday</days> <code>TRUE</code> <indice>CHECK</indice> </TEAM> </OFFICE> <OFFICE name="LCO"> <DEPARTAMENT name="LCO1"> <days>wednesday:saturday</days> <code>TRUE</code> <indice>CHECK</indice> </DEPARTAMENT> <TEAM name="LCO2"> <days>wednesday:saturday</days> <code>TRUE</code> <indice>CHECK</indice> </TEAM> </OFFICE> <OFFICE name="ACO"> <DEPARTAMENT name="ACO1"> <days>monday</days> <code>False</code> <indice>CHECK</indice> </DEPARTAMENT> <TEAM name="ACO2"> <days>tuesday</days> <code>False</code> <indice>CHECK</indice> </TEAM> </OFFICE> </SCHEDULES> </COMPANY>
问题代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="text()"> <xsl:value-of select="translate(.,'True','TRUE')"/> <xsl:value-of select="translate(.,'check','CHECK')"/> </xsl:template> </xsl:stylesheet>
问题分析与修复
你的代码核心问题在于文本处理模板里的两个<xsl:value-of>会将原始文本输出两次:第一个translate处理后输出一次,第二个又基于原始文本处理后再输出一次,导致结果重复,且两次转换没有叠加效果。
正确的做法是将两次translate链式调用,让第二次转换基于第一次的结果执行,并且只输出一次处理后的文本:
修正后的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="text()"> <xsl:value-of select="translate(translate(.,'True','TRUE'), 'check','CHECK')"/> </xsl:template> </xsl:stylesheet>
说明
- 保留了原有的身份模板(匹配
*的模板),确保XML结构完整复制。 - 文本处理模板中,通过嵌套
translate函数,先将"True"转为"TRUE",再基于这个结果将"check"转为"CHECK",最后一次性输出处理后的文本。 - 这样既完成了两次替换,又不会重复输出内容,完全符合需求。
内容的提问来源于stack exchange,提问作者runy29
相关产品推荐
相关产品推荐

