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 显示:
- 问题:我希望
empty-select
元素包含文本“不匹配”
- 解决方法:在测试字符串和正则表达式前加上“x”,以便 analyze-string 获得非空字符串。不优雅。
问题:这是 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 ...
.
我正在使用 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 显示:
- 问题:我希望
empty-select
元素包含文本“不匹配” - 解决方法:在测试字符串和正则表达式前加上“x”,以便 analyze-string 获得非空字符串。不优雅。
问题:这是 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 ...
.