如果元素包含字母,如何写xslt?

时间:2011-12-05 14:05:20

标签: regex xslt

Sth应该是所有字母或正则表达式[A-Z]。如何将xslt与正则表达式结合起来?

 <xsl:if test="string-contains(//ns0:elem/value, 'sth')">


        </xsl:if>

3 个答案:

答案 0 :(得分:10)

XPath / XSLT 1.0不支持正则表达式,但可以使用基本字符串函数执行简单验证。

<强>白名单

XPath 1.0 translate函数可用于模拟白名单:

<xsl:variable name="alpha" 
              select="'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:if test="string-length(translate(., $alpha, '')) &gt; 0">
    <!-- context node contains non-alpha characters -->
</xsl:if>

测试使用translate首先删除所有大写和小写字母。如果结果字符串的长度不为零,则原始字符串必须包含其他字符。

请注意,上面的表达式可以简化为:

<xsl:if test="translate(., $alpha, '')">

...因为任何非空字符串的计算结果为true。

<强>黑名单

使用双翻译方法将$alpha视为黑名单:

<xsl:if test="translate(., translate(., $alpha, ''), '')">
    <!-- context-node contains characters on the blacklist (in $alpha) -->
</xsl:if>

内部translate返回一个字符串,其中删除了所有字母字符,然后将其用作第二个translate调用的模板,从而生成仅包含字母字符的字符串。如果此字符串非零,则我们在黑名单中找到一个字符。这是一种经典的方法。例如,参见上一个关于SO的问题:

黑名单测试也可以这样执行:

not(string-length(translate(., $alpha, ''))=string-length())

如果删除所有列入黑名单的字符后字符串的长度不等于原始字符串的长度,则该字符串必须在黑名单中包含一个字符。

<强>摘要

黑名单和白名单实际上是同一枚硬币的两面。以下演示了它们的用法:

<xsl:if test="translate(., $alpha, '')">
    [contains some characters not on the list]
</xsl:if> 
<xsl:if test="not(translate(., $alpha, ''))">
    [contains only characters on the list]
</xsl:if> 
<xsl:if test="translate(., translate(., $alpha, ''), '')">
    [contains some characters on the list]
</xsl:if>
<xsl:if test="not(translate(., translate(., $alpha, ''), ''))">
    [contains only characters not on the list]
</xsl:if>

答案 1 :(得分:2)

在XPath 1.0(适用于XSLT 1.0)中,您没有正则表达式工具(您只有containsstarts-with等函数,请参阅下面的链接以获取更多信息)

在XPATH 2.0(适用于XSLT 2.0)中,您拥有matches函数和replace函数(请参阅下面的链接)。

要查看的网址:

XPath 1.0字符串函数:http://www.w3.org/TR/xpath/#section-String-Functions

XPath 2.0正则表达式函数:http://www.w3.org/TR/xpath-functions/#string.match

答案 2 :(得分:2)

  

如果你不能在xslt中使用正则表达式,如何在字符串中搜索字母?

好问题,+ 1。

使用

translate(., translate(., $vAlpha, ''), '')

这将生成当前节点的字符串值中的所有字符, $vAlpha

如果您想查看给定字符串$str是否仅包含字母而不包含其他字符,请使用

string-length(translate($str, $vAlpha, '')) = 0

完整的代码示例

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vUpper" select=
  "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>

 <xsl:variable name="vLower" select=
  "'abcdefghijklmnopqrstuvwxyz'"/>

 <xsl:variable name="vAlpha" select=
      "concat($vUpper, $vLower)"/>

 <xsl:variable name="vStr" select="'A12B_..c02d'"/>

 <xsl:template match="/">
  <xsl:value-of select=
    "translate($vStr,
               translate($vStr, $vAlpha, ''), '')
    "/>


    The string <xsl:value-of select="$vStr"/> has <xsl:text/>
    <xsl:value-of select=
    "string-length(translate($vStr, $vAlpha, ''))"/> <xsl:text/>
    non-letters

 </xsl:template>
</xsl:stylesheet>

将此转换应用于任何XML文档(未使用)时,会生成所需的正确结果

ABcd


    The string A12B_..c02d has 7
    non-letters

记住:上面的第一个XPath表达式演示了所谓的“双翻译方法”,首先由@Michael Kay提出。