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

时间:2021-06-27 21:20:46

I am using XSLT 1.0. My input information may contain these values

我正在使用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>

I want to find out those string that match the criteria:

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

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

In example above, for case 1,2,4 I should be able to do X processing. For case 3, I should be able to do Y processing.

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

I aim to use a regular expression (in XSLT 1.0).

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

For all the cases, the attribute can take any value of any length.

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

I tried use of match, but the processor returned an error. I tried use of translate function, but not sure if used the right way.

我尝试使用match,但是处理器返回一个错误。我尝试过翻译函数,但不确定是否用对了。

I am thinking about.

我在考虑。

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

How do I implement that using XSLT 1.0 syntax?

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

3 个解决方案

#1


14  

This solution really works in XSLT 1.0 (and is simpler, because it doesn't and needn't use the double-translate method.):

这个解决方案在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>

when applied on the provided XML fragment -- made a well-formed XML document:

当应用于提供的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>

the wanted, correct result is produced:

所需要的,正确的结果产生:

Processing Y


Processing X

Processing Y


Processing X

Do Note: Any attempt to use with a true XSLT 1.0 processor code like this (borrowed from another answer to this question) will fail with error:

请注意:任何试图使用真正的XSLT 1.0处理程序代码(从这个问题的另一个答案中借来)的尝试都会失败,而且会出错:

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

because in XSLT 1.0 it is forbidden for a match pattern to contain a variable reference.

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

#2


1  

XSLT does not support regular expressions, but you can fake it.

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

The following stylesheet prints an X processing message for all attribute elements having a string value containing at least one number and at least one letter (and Y processing for those that do not):

下面的样式表为所有属性元素打印一个X处理消息,该属性元素的字符串值至少包含一个数字和至少一个字母(不包含一个数字和至少一个字母):

<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>

Note: You said this:

注意:你说:

In example above, for case 1,2,4 I should be able to do X processing. for case 3, I should be able to do Y processing.

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

But that conflicts with your requirement, because case 1 does not contain a letter. If, on the other hand, you really want to match the equivalent of [a-zA-Z0-9], then use this:

但这与你的要求不一致,因为情形1没有字母。另一方面,如果你真的想匹配[a-zA-Z0-9],那么就用这个:

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

...which matches any attribute having at least one letter or number.

…匹配任何具有至少一个字母或数字的属性。

See the following question for more information on using translate in this way:

有关如何使用翻译的更多信息,请参见以下问题:

#3


0  

If you found this question because you're looking for a way to use regular expressions in XSLT 1.0, and you're writing an application using Microsoft's XSLT processor, you can solve this problem by using an inline C# script.

如果您发现了这个问题,因为您正在寻找在XSLT 1.0中使用正则表达式的方法,并且您正在使用Microsoft的XSLT处理程序编写应用程序,您可以使用内联c#脚本解决这个问题。

I've written out an example and a few tips in this thread, where someone was seeking out similar functionality. It's super simple, though it may or may not be appropriate for your purposes.

我已经在这个线程中写了一个例子和一些技巧,有人正在寻找类似的功能。它非常简单,尽管它可能适合也可能不适合你的目的。

#1


14  

This solution really works in XSLT 1.0 (and is simpler, because it doesn't and needn't use the double-translate method.):

这个解决方案在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>

when applied on the provided XML fragment -- made a well-formed XML document:

当应用于提供的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>

the wanted, correct result is produced:

所需要的,正确的结果产生:

Processing Y


Processing X

Processing Y


Processing X

Do Note: Any attempt to use with a true XSLT 1.0 processor code like this (borrowed from another answer to this question) will fail with error:

请注意:任何试图使用真正的XSLT 1.0处理程序代码(从这个问题的另一个答案中借来)的尝试都会失败,而且会出错:

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

because in XSLT 1.0 it is forbidden for a match pattern to contain a variable reference.

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

#2


1  

XSLT does not support regular expressions, but you can fake it.

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

The following stylesheet prints an X processing message for all attribute elements having a string value containing at least one number and at least one letter (and Y processing for those that do not):

下面的样式表为所有属性元素打印一个X处理消息,该属性元素的字符串值至少包含一个数字和至少一个字母(不包含一个数字和至少一个字母):

<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>

Note: You said this:

注意:你说:

In example above, for case 1,2,4 I should be able to do X processing. for case 3, I should be able to do Y processing.

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

But that conflicts with your requirement, because case 1 does not contain a letter. If, on the other hand, you really want to match the equivalent of [a-zA-Z0-9], then use this:

但这与你的要求不一致,因为情形1没有字母。另一方面,如果你真的想匹配[a-zA-Z0-9],那么就用这个:

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

...which matches any attribute having at least one letter or number.

…匹配任何具有至少一个字母或数字的属性。

See the following question for more information on using translate in this way:

有关如何使用翻译的更多信息,请参见以下问题:

#3


0  

If you found this question because you're looking for a way to use regular expressions in XSLT 1.0, and you're writing an application using Microsoft's XSLT processor, you can solve this problem by using an inline C# script.

如果您发现了这个问题,因为您正在寻找在XSLT 1.0中使用正则表达式的方法,并且您正在使用Microsoft的XSLT处理程序编写应用程序,您可以使用内联c#脚本解决这个问题。

I've written out an example and a few tips in this thread, where someone was seeking out similar functionality. It's super simple, though it may or may not be appropriate for your purposes.

我已经在这个线程中写了一个例子和一些技巧,有人正在寻找类似的功能。它非常简单,尽管它可能适合也可能不适合你的目的。