XSLT 3: xsl:analyze-string of empty nodeset 不执行 xsl:non-matching-substring

XSLT 3: xsl:analyze-string of empty nodeset does not execute xsl:non-matching-substring

我正在使用 xsl:analyze-string 来解析可能不存在的节点内的文本。

<xsl:analyze-string select="inexistant" regex="^([0-9]+)$">

根据XSLT 3.0

If the result of evaluating the select expression is an empty sequence, it is treated as a zero-length string.

我希望 analyze-string 发现一个空字符串与我的正则表达式不匹配,因此 

xsl:non-matching-substring 被执行。但这实际上并没有发生:相反,analyze-string 不会产生任何结果。

我在 Oxygen-XML 中使用 Saxon 9.9.1.7。 Saxonica's analyze-string documentation 没有具体选择空节点集。

XSLT Fiddle here 显示:

问题:这是 Saxon 9 中的错误还是我误解了 XSLT 3.0 规范?

我认为 Saxon 的行为符合以下部分中的规定:

The processor starts by setting the current position to position zero, and the current non-matching substring to a zero-length string

If there is no match:

If the current position is the last position (that is, just after the last character):

If the current non-matching substring has length greater than zero, evaluate the xsl:non-matching-substring sequence constructor with the current non-matching substring as the context item.

Exit.

所以你是对的,空序列被视为零长度字符串,但由于零长度字符串不会产生任何不匹配的子字符串,因此 xsl:non-matching-substring 未被评估。

测试用例 https://github.com/w3c/xslt30-test/blob/master/tests/insn/analyze-string/analyze-string-035.xsl 在测试套件中进行检查,执行

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
    
      <!-- PURPOSE: test xsl:analyze-string applied to an empty sequence - error in 2.0, treated as "" in 2.1. -->
      
      <xsl:param name="in" select="()"/>
    
      <xsl:template match="/">
        <out>
          <xsl:analyze-string select="$in" regex="[A-Z]">
           <xsl:matching-substring><m/></xsl:matching-substring>
           <xsl:non-matching-substring><n/></xsl:non-matching-substring>
          </xsl:analyze-string>      
        </out>
      </xsl:template>
      
    
    </xsl:stylesheet>

它应该 (https://github.com/w3c/xslt30-test/blob/master/tests/insn/analyze-string/_analyze-string-test-set.xml#L288) 产生结果 <out/>

无论如何您都在使用 XSLT 3,您可能想看看 analyze-string 函数是否是您可以做的替代方法,例如let $analyze-result := analyze-string(inexistant, '^([0-9]+)$') return if (not($analyze-result/*)) then (: handle nor match nor non-match here :) else ....