xsl:matching-substring всегда возвращает false

Я пытаюсь написать функцию, которая получает доменное имя из текста URL-адреса в файле XML, например www.example.com.

 <xsl:function name="fdd:get-domain">
    <xsl:param name="url"/>

    <xsl:analyze-string select="$url" regex="^(.*)://([a-zA-Z0-9\-\.]?[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?)(/.*)$">
        <xsl:matching-substring>
            <xsl:value-of select="regex-group(1)"/>
        </xsl:matching-substring>

        <xsl:non-matching-substring>
            <xsl:value-of select="false()"/>
        </xsl:non-matching-substring>

    </xsl:analyze-string>
 </xsl:function>

Эта функция всегда возвращает false. Я не уверен, что мне не хватает в этом.


person MSW    schedule 27.01.2012    source источник


Ответы (1)


Внутри значения атрибута каждые { и } должны быть удвоены (чтобы отличить их от одиночных символов, обозначающих AVT. Просто удвоив фигурные скобки:

^(.*)://([a-zA-Z0-9\-\.]?[a-zA-Z0-9\-\.]+\.[a-zA-Z]{{2,3}}(/\S*)?)(/.*)$

с этим исправлением при таком вызове:

fdd:get-domain('http://www.abc/cpm/page.aspx')

результат:

http

Я предполагаю, что вы действительно хотите получить домен, как это делает этот модифицированный код (как регулярное выражение, так и индекс группы регулярных выражений):

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

 <xsl:template match="/">
  <xsl:sequence select="fdd:get-domain('http://www.abc.com/cpm/page.aspx')"/>
 </xsl:template>

      <xsl:function name="fdd:get-domain">
        <xsl:param name="url"/>

        <xsl:analyze-string select="$url" regex=
"^(.*)://([a-zA-Z0-9\-\.]?[a-zA-Z0-9\-\.]+\.[a-zA-Z]{{2,3}})(/\S*)?(/.*)$">
            <xsl:matching-substring>
                <xsl:value-of select="regex-group(2)"/>
            </xsl:matching-substring>

            <xsl:non-matching-substring>
                <xsl:value-of select="false()"/>
            </xsl:non-matching-substring>

        </xsl:analyze-string>
     </xsl:function>
</xsl:stylesheet>

Когда это преобразование применяется к любому XML-документу (не используемому), создается желаемый правильный результат:

www.abc.com

Обновление. Как напомнил Майкл Кей, необходимости дублировать любые фигурные скобки можно избежать, если регулярное выражение указано как контекст переменной, а эта переменная указана как AVT в атрибуте regex атрибута xsl:analyze-string. :

<xsl:analyze-string select="$url" regex="{$vRegEx}"
                    flags="mx" >

У этого есть еще одно преимущество — мы можем разделить подвыражения RegEx на разные строки и даже смешивать их с комментариями.

Вот преобразованное преобразование:

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

 <xsl:variable name="vRegEx">

   ^(.*) <!-- The scheme -->

   ://

   ([a-zA-Z0-9\-\.]?[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}) <!-- The domain -->

   (/\S*)?(/.*)$  <!-- the path and query string -->

 </xsl:variable>

     <xsl:template match="/">
      <xsl:sequence select="fdd:get-domain('http://www.abc.com/cpm/page.aspx')"/>
     </xsl:template>

          <xsl:function name="fdd:get-domain">
            <xsl:param name="url"/>

            <xsl:analyze-string select="$url" regex="{$vRegEx}"
                                flags="mx" >
                <xsl:matching-substring>
                    <xsl:value-of select="regex-group(2)"/>
                </xsl:matching-substring>

                <xsl:non-matching-substring>
                    <xsl:value-of select="false()"/>
                </xsl:non-matching-substring>

            </xsl:analyze-string>
         </xsl:function>
</xsl:stylesheet>
person Dimitre Novatchev    schedule 27.01.2012
comment
Правильный ответ. Если удвоение завитков становится проблемой, может помочь помещение регулярного выражения в переменную (используйте regex="{$regex}") - person Michael Kay; 27.01.2012
comment
@MichaelKay: Да, и еще одно преимущество помещения регулярного выражения в переменную заключается в том, что тогда регулярное выражение может быть представлено частями в разных строках (в разных текстовых узлах), каждому из которых предшествует комментарий - что-то, что чаще всего необходимо, чем нет в case uf написание и понимание регулярных выражений. - person Dimitre Novatchev; 27.01.2012
comment
@maheshexp: AVT — это шаблоны значений атрибутов, читайте об этом в спецификации: w3.org /TR/xslt#шаблоны-значения-атрибутов - person Dimitre Novatchev; 28.01.2012
comment
@maheshexp: Да, это очень помогает. Я создал лексеры для JSON и XPath 2.0, и довольно длинные регулярные выражения разбиты на небольшие части с поясняющими комментариями — огромная разница, делающая это возможным. - person Dimitre Novatchev; 28.01.2012