是否可以使用fn:analyze-string
(XSLT 2.0)生成与xsl:analyze-string
(XPath 3.0)相同的输出?
输入字符串abcdefg
的一些示例:
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>
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>
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)发现组的父/子关系以促进递归。但我很好奇是否有一些我忽略的事情。
答案 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> </xsl:text>
<f:analyze-string-result>
<xsl:text> </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> </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> </xsl:text>
</f:analyze-string-result>
<xsl:text> </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>