Как использовать регулярное выражение в XSLT 1.0? - PullRequest
17 голосов
/ 18 января 2012

Я использую 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 ]

14 голосов
/ 19 января 2012

Это решение действительно работает в 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

Do Note : Любая попытка использовать с таким истинным кодом процессора XSLT 1.0, как этот (заимствованный из другого ответа на этот вопрос), завершится с ошибкой:

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

потому что в XSLT 1.0 запрещено, чтобы шаблон совпадения содержал ссылку на переменную.

1 голос
/ 08 октября 2016

Если вы нашли этот вопрос, потому что вы ищете способ использования регулярных выражений в XSLT 1.0, и вы пишете приложение с использованием процессора XSLT от Microsoft, вы можете решить эту проблему с помощью встроенного сценария C # ..

Я написал пример и несколько советов в этой теме , где кто-то искал подобную функциональность.Это очень просто, хотя может и не подходить для ваших целей.

1 голос
/ 19 января 2012

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 таким образом:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...