Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

regex - How do I use a regular expression in XSLT 1.0?

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

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

I aim to use a regular expression (in 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.

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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

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

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...