如何在XSLT 1.0中使用正则表达式?

时间:2012-01-18 19:35:46

标签: regex xslt

我正在使用XSLT 1.0。 我的输入信息可能包含这些值

<!--case 1-->
<attribute>123-00</attribute>

<!--case 2-->
<attribute>Abc-01</attribute>

<!--case 3-->
<attribute>--</attribute>

<!--case 4-->
<attribute>Z2-p01</attribute>

我想找出符合条件的字符串:

if string has at least 1 alphabet AND has at least 1 number,
then 
do X processing
else
do Y processing

在上面的示例中,对于案例1,2,4,我应该能够进行X处理。对于案例3,我应该能够进行Y处理。

我的目标是使用正则表达式(在XSLT 1.0中)。

对于所有情况,该属性可以采用任何长度的任何值。

我尝试使用match,但处理器返回了错误。 我尝试使用translate函数,但不确定是否以正确的方式使用。

我正在考虑。

if String matches [a-zA-Z0-9]* 
then do X processing
else
do y processing.

如何使用XSLT 1.0语法实现它?

3 个答案:

答案 0 :(得分:14)

此解决方案在XSLT 1.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="vDigits" select=
 "'0123456789'"/>

 <xsl:template match="attribute">
  <xsl:choose>
   <xsl:when test=
    "string-length() != string-length(translate(.,$vAlpha,''))
    and
     string-length() != string-length(translate(.,$vDigits,''))">

    Processing X
   </xsl:when>
   <xsl:otherwise>
    Processing Y
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML片段时 - 制作格式良好的XML文档

<t>
    <!--case 1-->
    <attribute>123-00</attribute>
    <!--case 2-->
    <attribute>Abc-01</attribute>
    <!--case 3-->
    <attribute>--</attribute>
    <!--case 4-->
    <attribute>Z2-p01</attribute>
</t>

产生了想要的正确结果

Processing Y


Processing X

Processing Y


Processing X

请注意:任何尝试使用这样的真正的XSLT 1.0处理器代码(从该问题的另一个答案中借用)都将失败并显示错误:

<xsl:template match=
"attribute[
           translate(.,
                     translate(.,
                               concat($upper, $lower),
                               ''),
                     '')
         and
           translate(., translate(., $digit, ''), '')]
 ">

因为在XSLT 1.0中禁止匹配模式包含变量引用。

答案 1 :(得分:1)

XSLT 不支持正则表达式,但您可以伪造它。

以下样式表为所有X processing元素打印attribute消息,其中包含至少包含一个数字至少一个字母的字符串值(以及Y processing对于那些不这样做的人:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
    <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
    <xsl:variable name="digit" select="'0123456789'"/>
    <xsl:template match="attribute">
        <xsl:choose>
            <xsl:when test="
                translate(., translate(., concat($upper, $lower), ''), '') and 
                translate(., translate(., $digit, ''), '')">
                <xsl:message>X processing</xsl:message>
            </xsl:when>
            <xsl:otherwise>
                <xsl:message>Y processing</xsl:message>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

注意:你这样说:

  

在上面的例子中,对于情况1,2,4我应该能够进行X处理。   对于案例3,我应该可以进行Y处理。

但这与您的要求相冲突,因为案例1 包含一个字母。另一方面,如果你真的想匹配[a-zA-Z0-9]的等价物,那么请使用:

translate(., translate(., concat($upper, $lower, $digit), ''), '')

...匹配任何至少有一个字母编号的attribute

有关以这种方式使用translate的更多信息,请参阅以下问题:

答案 2 :(得分:1)

如果您发现此问题是因为您正在寻找在XSLT 1.0中使用正则表达式的方法,并且您正在使用Microsoft的XSLT处理器编写应用程序,则可以通过以下方法解决此问题:使用内联C#脚本

我在this thread中写了一个示例和一些提示,其中有人正在寻找类似的功能。它非常简单,但它可能适用于您的目的,也可能不适合。