XSLT 中的正则表达式组(last())

regex-group(last()) in XSLT

正在使用分析字符串链接输入中的某些文本,但无法在脚本中检索 regex-group(last())

您可以在 https://xsltfiddle.liberty-development.net/bnnZVG

查看转换

如你所见,当前输出

<?xml version="1.0" encoding="UTF-8"?>
<TEST>
    <P>Check <Link ID="ID0001">AbC,2013</Link>AbC,2013Marking</P>
    <P>Check <Link ID="ID0001">ABc, 2013</Link>ABc, 2013Marking</P>
    <P>Check <Link ID="ID0001">ABC 2013</Link>ABC 2013Marking</P>
    <P>Check <Link ID="ID0001">ABC</Link>ABCMarking</P>
    <P>Check <Link ID="ID0002">BCA,2013</Link>BCA,2013Marking</P>
    <P>Check <Link ID="ID0002">bcA, 2013</Link>bcA, 2013Marking</P>
    <P>Check <Link ID="ID0002">BCa 2013</Link>BCa 2013Marking</P>
    <P>Check <Link ID="ID0002">bcA</Link>bcAMarking</P>
</TEST>

但预期输出是

<?xml version="1.0" encoding="UTF-8"?>
<TEST>
    <P>Check <Link ID="ID0001">AbC,2013</Link> Marking</P>
    <P>Check <Link ID="ID0001">ABc, 2013</Link> Marking</P>
    <P>Check <Link ID="ID0001">ABC 2013</Link> Marking</P>
    <P>Check <Link ID="ID0001">ABC</Link> Marking</P>
    <P>Check <Link ID="ID0002">BCA,2013</Link> Marking</P>
    <P>Check <Link ID="ID0002">bcA, 2013</Link> Marking</P>
    <P>Check <Link ID="ID0002">BCa 2013</Link> Marking</P>
    <P>Check <Link ID="ID0002">bcA</Link> Marking</P>
</TEST>

提前致谢

您希望在 xsl:analyze-string 中调用 last() 得到什么值?如果您查看 https://www.w3.org/TR/xslt-30/#element-analyze-string 中的最后一段,它会说:

A matching substring is processed using the xsl:matching-substring element, a non-matching substring using the xsl:non-matching-substring element. Each of these elements takes a sequence constructor as its content. If the element is absent, the effect is the same as if it were present with empty content. In processing each substring, the contents of the substring will be the context item (as a value of type xs:string); the position of the substring within the sequence of matching and non-matching substrings will be the context position; and the number of matching and non-matching substrings will be the context size.

因此,last() returns 上下文大小应该等于匹配和不匹配子串的数量。

我知道这不是一个完整的答案,但它太长了,不能用作评论。您可能还想编辑您的问题并用简单的语言告诉我们您链接到的 XSLT 应该实现什么,然后我们可能会帮助建议一个合适的 XSLT 解决方案。

另请注意,带有 XPath 3 的 XSLT 3 具有 analyze-string 函数,其中 returns 具有匹配和组的 XML 结构,因此 processing/consuming 可能会帮助您提取你想要的内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:key name="testkey" match="link" use="linkname"/>

    <xsl:variable name="testcheck">
        <link name="ID0001">
            <linkname>abc, 2013</linkname>
            <linkname>abc</linkname>
        </link>
        <link name="ID0002">
            <linkname>bca, 2013</linkname>
            <linkname>bca</linkname>
        </link>
    </xsl:variable>

    <xsl:variable name="test">
        <xsl:text>(</xsl:text>
        <xsl:for-each select="$testcheck//linkname">
            <xsl:if test="position() ne 1"><xsl:text>|</xsl:text></xsl:if>
            <xsl:value-of select="."/>
        </xsl:for-each>
        <xsl:text>)</xsl:text>
    </xsl:variable>

    <xsl:variable name="regex" as="xs:string"
      select="concat('(^|\W)', replace($test, ', ([0-9][0-9][0-9][0-9])', '(, |,| )?'), '($|\W)')"/>

    <xsl:template match="text()[matches(., $regex, 'i')]">
         <xsl:apply-templates select="analyze-string(., $regex, 'i')" mode="extract"/>
    </xsl:template>

    <xsl:mode name="extract" on-no-match="text-only-copy"/>

    <xsl:template match="fn:match/fn:group[@nr = 2]" mode="extract">
        <Link ID="{$testcheck//key('testkey', lower-case(replace(current(), '(, |,| )([0-9][0-9][0-9][0-9])', ', ')))/@name}">
            <xsl:value-of select="."/>
        </Link>          
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bnnZVG/2 给出

<TEST>
    <P>Check <Link ID="ID0001">AbC,2013</Link> Marking</P>
    <P>Check <Link ID="ID0001">ABc, 2013</Link> Marking</P>
    <P>Check <Link ID="ID0001">ABC 2013</Link> Marking</P>
    <P>Check <Link ID="ID0001">ABC</Link> Marking</P>
    <P>Check <Link ID="ID0002">BCA,2013</Link> Marking</P>
    <P>Check <Link ID="ID0002">bcA, 2013</Link> Marking</P>
    <P>Check <Link ID="ID0002">BCa 2013</Link> Marking</P>
    <P>Check <Link ID="ID0002">bcA</Link> Marking</P>
</TEST>