regex - Duplicate fn:analyze-string() output using xsl:analyze-string? -
is possible generate output identical fn:analyze-string
(xpath 3.0) using xsl:analyze-string
(xslt 2.0)?
some examples input string 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>
i suspect it's not possible because xsl:analyze-string
not provide methods to: 1) know how many groups there, or 2) discover parent/child relationships of groups facilitate recursion. i'm curious if there have overlooked.
you can make bit easier changing syntax of regex, using <g> </g>
grouping rather ()
(it possible tiresome not , instead analyse regex , determine groups)
once have group structure can generate normal regex using ()
pass xsl:analyze-function
adding groups every text run grouped , can retrieved later regex-group()
.
not extensively tested there may bugs this, , seems work on examples.
<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>
produces
$ 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>
Comments
Post a Comment