1

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

输入字符串的一些示例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>
    

我怀疑这是不可能的,因为xsl:analyze-string没有提供以下方法:1)知道那里有多少组,或者 2)发现组的父/子关系以促进递归。但我很好奇是否有我忽略的东西。

4

1 回答 1

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>
于 2013-10-05T12:49:21.657 回答