使用xsl:analyze-string复制fn:analyze-string()输出?

时间:2013-09-03 19:32:20

标签: regex xslt xpath

是否可以使用fn:analyze-string(XSLT 2.0)生成与xsl:analyze-string(XPath 3.0)相同的输出?

输入字符串abcdefg的一些示例:

  1. regex="^a((b(c))d)(efg)$"

    <s:analyze-string-result xmlns:s="http://www.w3.org/2009/xpath-functions/analyze-string">
        <s:match>a<s:group nr="1">
            <s:group nr="2">b<s:group nr="3">c</s:group>
            </s:group>d</s:group>
            <s:group nr="4">efg</s:group>
        </s:match>
    </s:analyze-string-result>
    
  2. regex="^((a(bc)d)(.*))$

    <s:analyze-string-result xmlns:s="http://www.w3.org/2009/xpath-functions/analyze-string">
        <s:match>
            <s:group nr="1">
                <s:group nr="2">a<s:group nr="3">bc</s:group>d</s:group>
                <s:group nr="4">efg</s:group>
            </s:group>
        </s:match>
    </s:analyze-string-result>
    
  3. regex="^(((a)(b)(cde)(.*)))$"

    <s:analyze-string-result xmlns:s="http://www.w3.org/2009/xpath-functions/analyze-string">
        <s:match>
            <s:group nr="1">
                <s:group nr="2">
                    <s:group nr="3">a</s:group>
                    <s:group nr="4">b</s:group>
                    <s:group nr="5">cde</s:group>
                    <s:group nr="6">fg</s:group>
                </s:group>
            </s:group>
        </s:match>
    </s:analyze-string-result>
    
  4. 我怀疑这是不可能的,因为xsl:analyze-string不提供以下方法:1)知道有多少组,或2)发现组的父/子关系以促进递归。但我很好奇是否有一些我忽略的事情。

1 个答案:

答案 0 :(得分:1)

通过更改正则表达式的语法,使用<g> </g>进行分组而不是(),您可以更轻松一点(这可能会令人厌烦,但不要这样做,而是分析正则表达式和确定小组)

获得组结构后,您可以使用()生成正常的正则表达式,以便传递给xsl:analyze-function添加额外的组,以便对每个文本运行进行分组,以后可以使用regex-group()进行检索

没有经过广泛测试,因此可能存在类似的错误,而且它似乎适用于您的示例。

<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:f="data:,f"
        exclude-result-prefixes="xs"
        >

<xsl:output omit-xml-declaration="yes"/>

<xsl:function name="f:analyze-string">
 <xsl:param name="s"/>
 <xsl:param name="r"/>
 <xsl:variable name="rr">
  <xsl:apply-templates mode="a-s" select="$r"/>
 </xsl:variable>
 <xsl:text>&#10;</xsl:text>
 <f:analyze-string-result>
  <xsl:text>&#10;</xsl:text>
  <xsl:analyze-string select="$s" regex="{$rr}">
   <xsl:matching-substring>
    <f:match>
     <xsl:variable name="m" select="."/>
     <xsl:apply-templates mode="g" select="$r"/>
    </f:match>
    <xsl:text>&#10;</xsl:text>
   </xsl:matching-substring>
   <xsl:non-matching-substring>
    <f:non-match>
     <xsl:value-of select="."/>
    </f:non-match>
   </xsl:non-matching-substring>
  </xsl:analyze-string>
  <xsl:text>&#10;</xsl:text>
 </f:analyze-string-result>
 <xsl:text>&#10;</xsl:text>
</xsl:function>

<xsl:template mode="a-s" match="g">
 <xsl:text>(</xsl:text>
 <xsl:apply-templates mode="a-s"/>
 <xsl:text>)</xsl:text>
</xsl:template>

<xsl:template mode="a-s" match="text()[../g]">
 <xsl:text>(</xsl:text>
 <xsl:value-of select="."/>
 <xsl:text>)</xsl:text>
</xsl:template>

<xsl:template mode="g" match="g">
 <f:group>
  <xsl:attribute name="nr">
   <xsl:number level="any"/>
  </xsl:attribute>
  <xsl:apply-templates mode="g"/>
 </f:group>
</xsl:template>

<xsl:template mode="g" match="text()">
 <xsl:variable name="n">
  <xsl:number count="g|text()[../g]" level="any"/>
 </xsl:variable>
 <xsl:value-of select="regex-group(xs:integer($n))"/>
</xsl:template>

<xsl:template name="main">

 <!-- regex="^a((b(c))d)(efg)$" -->
 <xsl:variable name="r">a<g><g>b<g>c</g></g>d</g><g>efg</g>$</xsl:variable>
 <xsl:sequence  select="f:analyze-string('abcdefg',$r)"/>

 <!-- regex="^((a(bc)d)(.*))$ -->
 <xsl:variable name="r"><g><g>a<g>bc</g>d</g><g>.*</g></g>$</xsl:variable>
 <xsl:sequence  select="f:analyze-string('abcdefg',$r)"/>


<!-- regex="^(((a)(b)(cde)(.*)))$" -->
 <xsl:variable name="r"><g><g><g>a</g><g>b</g><g>cde</g><g>.*</g></g></g>$</xsl:variable>
 <xsl:sequence  select="f:analyze-string('abcdefg',$r)"/>


</xsl:template>

</xsl:stylesheet>

可生产

$ saxon9 -it main analyse.xsl

<f:analyze-string-result xmlns:f="data:,f">
<f:match>a<f:group nr="1"><f:group nr="2">b<f:group nr="3">c</f:group></f:group>d</f:group><f:group nr="4">efg</f:group></f:match>

</f:analyze-string-result>

<f:analyze-string-result xmlns:f="data:,f">
<f:match><f:group nr="1"><f:group nr="2">a<f:group nr="3">bc</f:group>d</f:group><f:group nr="4">efg</f:group></f:group></f:match>

</f:analyze-string-result>

<f:analyze-string-result xmlns:f="data:,f">
<f:match><f:group nr="1"><f:group nr="2"><f:group nr="3">a</f:group><f:group nr="4">b</f:group><f:group nr="5">cde</f:group><f:group nr="6">fg</f:group></f:group></f:group></f:match>

</f:analyze-string-result>