XSLT 正则表达式只接受字符串中的几个字符

XSLT regular expression to accept only few characters in a string

我正在编写一个只允许以下特殊字符的正则表达式:

- _ * & . , #

我写了下面的函数,它将避免除下面模式中提到的所有字符:

<xsl:function name="wd:allowed_characters">
    <xsl:param name="input_param" />
    <xsl:if test="$input_param !=' '" >
        <xsl:value-of select="normalize-space(replace($input_param,'[^.#, \- _ * a-zA-Z0-9]',''))" />
    </xsl:if>
</xsl:function>

我的问题是每当我尝试在模式中的任何地方添加 & 时,都会出现以下错误:

Severity: fatal
Description: The entity name must immediately follow the '&' in the entity

Severity: error
Description: Failed to compile stylesheet. 1 error detected.

我想知道如何像其他特殊字符一样在模式中添加 &

据我所知,在XML中,不能使用'&'的直接键,应该是'&[A-z0-9]+;'的组合。在 XML 中,我们可以使用 '&'或“&”实体格式。 在正则表达式中,可以使用 '[^.#, &&- _ * a-zA-Z0-9]'。

XSLT 是用 XML 编写的,因此 XSLT 样式表的源代码必须格式正确(通常也是有效的)XML。 XML中有五个特殊字符:<>&"',大致只能这样使用:

  • 在属性值内部,如果引号也是边界字符,则必须转义引号,如 test=" &quot;foo&quot; "。通常,您可以通过用另一个引号将其括起来来编写属性值:test=' "foo" 'test=" 'foo' " 都是有效的。在通常在属性值内用 XSLT 编写的 XPath 中,这是编写字符串文字的常用方法(这是您在上面的代码中已经在做的)。
  • 无论是在属性值中还是在允许自由文本的任何其他地方,您必须始终分别在 &lt;&amp; 中转义 <&
  • > 永远不需要转义,但很多人都这样做。
  • 五个 "escapes" 始终可用作命名实体引用,无论是否存在 DTD:&lt;&gt;&amp;&quot;&apos;,其他命名实体引用首先需要在 DTD 中声明(正如 &nbsp; 经常做的那样)。
  • 仅在 CDATA 部分(和注释中)您不需要转义这些字符中的任何一个:<![CDATA[<hello>&]]>&lt;hello>&amp; 完全相同。 CDATA 部分只能在文本节点中使用,而不能在属性值中使用。

这常常令人困惑。如果源文档在 XML 中包含 &lt;,您将无法通过将其与字符串 &lt; 进行比较来找到它,因为本质上它只是 < 字符.相反,您必须搜索 <。但是,由于 XSLT 是用 XML 编写的,因此编写 <xsl:if test="contains(.,<)" 将搜索 < 字符,而不是四字符字符串 &lt;.

关于你的问题,你的表述可以简单写成:

  • replace($input_param,'[^&amp;.#,_*a-zA-Z0-9-]','')
  • 我删除了空格(不确定是有意的)
  • 我把 - 放在最后,不需要转义
  • 您的 xsl:if 是多余的:normalize-space 将使仅由空格组成的字符串与空字符串相同。有或没有 xsl:if 都会有相同的结果

注意:由于转义、引用问题和其他事情的复杂性,通常在变量的序列构造函数中编写正则表达式,以防止这些问题首先发生(添加了 x-允许在正则表达式中使用空格的修饰符):

<xsl:variable name='regex' as='xs:string'>
    [^&amp;.#,_*a-zA-Z0-9-]
</xsl:variable>

<xsl:function name="wd:allowed_characters" as="xs:string">
    <xsl:param name="input_param" as="xs:string" />
    <xsl:value-of select="
       normalize-space(
       replace($input_param, $regex, '', 'x'))" />
</xsl:function>