Xslt xsl:匹配的子字符串始终返回“0”;假;

Xslt xsl:匹配的子字符串始终返回“0”;假;,xslt,xslt-2.0,xpath-2.0,Xslt,Xslt 2.0,Xpath 2.0,我正在尝试编写一个函数,该函数从XML文件(即www.example.com)中的URL文本获取域名 <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*)?)(/.*)$"&

我正在尝试编写一个函数,该函数从XML文件(即www.example.com)中的URL文本获取域名

 <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
。我不确定我在这方面遗漏了什么。

在属性值中,每个
{
}
必须加倍(以便将它们与表示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
www.abc.com
结果是

fdd:get-domain('http://www.abc/cpm/page.aspx')
http
www.abc.com
我猜您真的想获得域,正如这段修改过的代码(regex表达式和regex组索引)所做的那样:

<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>
更新:正如Michael Kay提醒的那样,如果将正则表达式指定为变量的上下文,并且在
xsl:analyze string
RegEx
属性中将该变量引用为AVT,则可以避免复制任何大括号:

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

这还有另一个好处——我们可以在不同的行上拆分正则表达式子表达式,甚至可以将它们与注释混合在一起

以下是重构后的转换:

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

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

在属性值内,每个
{
}
必须加倍(以便将它们与表示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
www.abc.com
结果是

fdd:get-domain('http://www.abc/cpm/page.aspx')
http
www.abc.com
我猜您真的想获得域,正如这段修改过的代码(regex表达式和regex组索引)所做的那样:

<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>
更新:正如Michael Kay提醒的那样,如果将正则表达式指定为变量的上下文,并且在
xsl:analyze string
RegEx
属性中将该变量引用为AVT,则可以避免复制任何大括号:

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

这还有另一个好处——我们可以在不同的行上拆分正则表达式子表达式,甚至可以将它们与注释混合在一起

以下是重构后的转换:

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

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

回答正确。如果卷曲的加倍变得很痛苦,那么将正则表达式放入变量中会有所帮助(使用
regex=“{$regex}”
)@MichaelKay:是的,将正则表达式放入变量中的另一个好处是,正则表达式可以在不同的行(不同的文本节点)上以部分的形式呈现,每个前面都有一条注释——在编写和理解正则表达式的情况下最需要的注释。@maheshexp:AVT是“属性值模板”在规范中阅读:@maheshexp:是的,这很有帮助。我已经为JSON和XPath 2.0构建了lexer,相当长的正则表达式被分成几个小的子部分,并解释注释——这是巨大的差异,这是可能的。回答正确。如果卷曲数加倍变得很痛苦,将正则表达式放入变量中会有帮助(使用
regex=“{$regex}”
)@MichaelKay:是的,将regex放入变量的另一个好处是,可以在不同的行(在不同的文本节点)上以部分的形式呈现regex,每个行前面都有一条注释——这在编写和理解regex时是最需要的。@maheshexp:AVT“属性值模板”在spec中读到:@maheshexp:是的,这很有帮助。我为JSON和XPath 2.0构建了词法分析器,相当长的正则表达式被分成了几个小的子部分,并解释注释——这是一个巨大的差异,使之成为可能。