1

如果我查看 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"/>

我知道这根本行不通,只是为了让我的请求有点视觉化。

任何想法 ?

4

2 回答 2

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\]*\)
于 2013-05-19T16:22:10.833 回答
1

我认为 XSLT 2.0 中的字符映射是在将结果树序列化为文件或流时应用的序列化功能,因此我看不出如何在转换期间将其应用于某个字符串或某个节点。

至于转义正则表达式模式的元字符,也许http://www.xsltfunctions.com/xsl/functx_escape-for-regex.html有帮助。

于 2013-05-19T12:46:24.737 回答