如果我查看xslt规范,似乎字符映射适用于整个文档,是否也可以在给定节点或模板中使用它?
示例:我有一个包含查找值的节点,但它们可能包含在另一个模板中使用时与正则表达式不兼容的字符。现在我使用一个效果很好的替换功能,但在几个字符变得非常难以阅读或维护之后。所以,如果我有这样的事情:
<xsl:variable name="myLookup" select="
replace(
replace(
replace(
replace(
string-join(/*/lookup/*, '|'),
'\[','\\['),
'\]','\\]'),
'\(','\\('),
'\)','\\)')
"/>
有没有办法实现类似下面的虚构示例?
<xsl:character-map name="escapechar">
<xsl:output-character character="[" string="\[" />
<xsl:output-character character="]" string="\]" />
<xsl:output-character character="(" string="\(" />
<xsl:output-character character=")" string="\)" />
</xsl:character-map>
<xsl:variable name="myLookup" select="string-join(/*/lookup/*, '|')" use-character-map="escapechar"/>
我知道这根本不起作用,只是让我的请求有点直观。
有什么想法吗?
答案 0 :(得分:1)
字符映射只是一个序列化功能,这意味着它只在生成转换的最终输出时执行。但是,您可以显着简化当前代码。
只需使用:
replace($pStr, '(\[|\]|\(|\))','\\$1')
以下是完整示例:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<xsl:value-of select="my:escape(.)"/>
</xsl:template>
<xsl:function name="my:escape" as="xs:string">
<xsl:param name="pStr" as="xs:string"/>
<xsl:value-of select="replace($pStr, '(\[|\]|\(|\))','\\$1')"/>
</xsl:function>
</xsl:stylesheet>
对以下XML文档应用此转换时:
<t>([a-z]*)</t>
产生了想要的正确结果:
\(\[a-z\]*\)
答案 1 :(得分:0)
我认为XSLT 2.0中的字符映射是在将结果树序列化为文件或流时应用的序列化功能,因此我看不到如何在转换期间将某个字符串应用于某个字符串或某个节点。
至于转义正则表达式模式的元字符,可能http://www.xsltfunctions.com/xsl/functx_escape-for-regex.html有帮助。