我有一个XML文件,它在子元素和属性中都有一些值。
如果我想在匹配特定值时替换某些文本,我该如何实现呢?
我尝试使用xlst:translate()
函数。但我不能将此函数用于xml中的每个元素或属性。
那么无论如何都要一次性替换/翻译价值?
<?xml version="1.0" encoding="UTF-8"?>
<Employee>
<Name>Emp1</Name>
<Age>40</Age>
<sex>M</sex>
<Address>Canada</Address>
<PersonalInformation>
<Country>Canada</country>
<Street1>KO 92</Street1>
</PersonalInformation>
</Employee>
输出:
<?xml version="1.0" encoding="UTF-8"?>
<Employee>
<Name>Emp1</Name>
<Age>40</Age>
<sex>M</sex>
<Address>UnitedStates</Address>
<PersonalInformation>
<Country>UnitedStates</country>
<Street1>KO 92</Street1>
</PersonalInformation>
</Employee>
在输出中,将文本从加拿大替换为美国。 因此,如果不对任何元素使用xslt:transform()函数,我应该能够将文本Canada替换为UnitedStates,而不管级别节点如何。 无论我在哪里找到'加拿大',我都应该能够在整个xml中替换为'UnitedStates'。 那我怎么能实现这个目标呢?
答案 0 :(得分:4)
予。 XSLT 1.0解决方案:
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:Reps>
<rep>
<old>replace this</old>
<new>replaced</new>
</rep>
<rep>
<old>cat</old>
<new>tiger</new>
</rep>
</my:Reps>
<xsl:variable name="vReps" select=
"document('')/*/my:Reps/*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:call-template name="replace">
<xsl:with-param name="pText" select="."/>
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<xsl:template match="text()" name="replace">
<xsl:param name="pText" select="."/>
<xsl:if test="string-length($pText)">
<xsl:choose>
<xsl:when test=
"not($vReps/old[contains($pText, .)])">
<xsl:copy-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vthisRep" select=
"$vReps/old[contains($pText, .)][1]
"/>
<xsl:variable name="vNewText">
<xsl:value-of
select="substring-before($pText, $vthisRep)"/>
<xsl:value-of select="$vthisRep/../new"/>
<xsl:value-of select=
"substring-after($pText, $vthisRep)"/>
</xsl:variable>
<xsl:call-template name="replace">
<xsl:with-param name="pText"
select="$vNewText"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于此XML文档时:
<t>
<a attr1="X replace this Y">
<b>cat mouse replace this cat dog</b>
</a>
<c/>
</t>
生成想要的正确结果:
<t>
<a attr1="X replaced Y">
<b>tiger mouse replaced tiger dog</b>
</a>
<c/>
</t>
<强>解释强>:
使用身份规则复制“按原样”某些节点。
我们执行多次替换,在my:Reps
如果文本节点或属性不包含任何rep-target,则按原样复制。
如果文字节点或属性包含要替换的文字(代表目标),则替换按照my:Reps
中指定的顺序完成强>
如果字符串包含多个字符串目标,则替换所有目标:首先是第一个目标的所有出现,然后是第二个目标的所有出现,...... ,持续最后一个目标的所有出现。
<强> II。 XSLT 2.0解决方案:
在XSLT 2.0中,可以简单地使用标准的XPath 2.0函数replace()
。但是,对于多次替换,解决方案仍然与上面指定的XSLT 1.0解决方案非常相似。