代码之家  ›  专栏  ›  技术社区  ›  Rupesh_Kr

XSLT中的regex组(last())

  •  -1
  • Rupesh_Kr  · 技术社区  · 6 年前

    使用分析字符串链接输入中的某些文本,但无法检索 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>
    

    提前谢谢

    1 回复  |  直到 6 年前
        1
  •  1
  •   Martin Honnen    6 年前

    你想打哪个电话 last() 里面 xsl:analyze-string ?如果你看最后一段 https://www.w3.org/TR/xslt-30/#element-analyze-string 它说:

    使用xsl:matching子字符串处理匹配的子字符串。 元素,使用xsl:non-matching子字符串的不匹配子字符串 元素。这些元素中的每一个都将序列构造函数作为其 内容。如果元素不存在,效果与 内容为空。在处理每个子字符串时, 子字符串的内容将是上下文项(作为类型的值 xs:string);子字符串在 匹配和不匹配的子字符串将是上下文位置;以及 匹配和不匹配子字符串的数目将是上下文 尺寸。

    因此 最后() 返回上下文大小,它应等于匹配子字符串和不匹配子字符串的数目。

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

    还请注意,具有xpath 3的XSLT 3具有 analyze-string 函数,该函数返回一个XML结构,其中包含匹配项和组,以便进行处理/消费,从而帮助您提取所需的内容:

    <?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])', '(, $1|,$1| $1)?'), '($|\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])', ', $2')))/@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>