我尝试用replace($val, 'amp;', '')
做到这一点,但似乎&
是解析器的原子实体。还有其他想法吗?
我需要它来摆脱双重转义,所以我在输入文件中有ᾰ
之类的结构。
UPD: 另外一个重要的通知:我必须仅在特定标签内部进行此替换,而不是在每个标签内部。
答案 0 :(得分:2)
如果序列化,则总是(如果支持)禁用 - 输出 - 逃避黑客,请参阅http://xsltransform.hikmatu.com/nbUY4kh转换
<root>
<foo>a & b</foo>
<bar>a & b</bar>
</root>
有选择地进入
<root>
<foo>a & b</foo>
<bar>a & b</bar>
</root>
在匹配<xsl:value-of select="." disable-output-escaping="yes"/>
的模板中使用foo/text()
:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="foo/text()">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
</xsl:transform>
要使用字符映射实现相同的选择性替换,您可以使用文档中未使用的字符替换foo
text()
子项(或必要时的后代)中的&符号,然后使用映射将它映射到未转义的&符号:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output use-character-maps="doe"/>
<xsl:character-map name="doe">
<xsl:output-character character="«" string="&"/>
</xsl:character-map>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="foo/text()">
<xsl:value-of select="replace(., '&', '«')"/>
</xsl:template>
</xsl:transform>
那样
<root>
<foo>a & b</foo>
<bar>a & b</bar>
</root>
也转换为
<root>
<foo>a & b</foo>
<bar>a & b</bar>
</root>
答案 1 :(得分:1)
如果您的XML包含&amp;#8112;并且您认为这是带有代码点8112的字符的双重转义表示,然后您可以使用XPath表达式将其转换为此字符
codepoints-to-string(xs:integer(replace($input, '&#([0-9]+);', $1)))
记住,如果在XSLT中编写此XPath表达式,则&
必须写为&
。