Saxon-JS 2 能否配置为接受 codepoints-to-string(8)?
能否通过配置解决?
不能直接照搬 Saxon-J 的 setXMLVersion(XML11)。对于题目中的 Saxon-JS 2,尚无足够依据确认存在等效的公开配置,能让 codepoints-to-string(8) 接受该字符。题目也没有给出 Saxon-JS 3 beta 的具体构建版本,因此无法保证升级后就能解决问题。
如果必须在 XPath 内生成实际的 U+0008 字符,可以使用支持 XML 1.1 的 Saxon-J,并设置 XML 版本。如果只需要在 JavaScript 中生成该字符,可以直接在 JavaScript 层完成。
为什么码点 8 会报错?
十进制 8 对应 U+0008,即退格控制字符。它不属于 XML 1.0 允许的字符。
XPath 3.1 的 fn:codepoints-to-string() 要求参数对应允许的 XML 字符,否则应抛出 FOCH0001。即使表达式没有读取 XML 文档,创建字符串时仍可能触发字符检查。XPath 3.1 函数规范
Saxon-J 的 XML 版本配置会影响 codepoints-to-string() 允许的字符范围,因此题目中的 Java 配置能够改变这一行为。Saxon 字符函数说明
必须在 XPath 内生成该字符时怎么办?
可以将相关处理放到 Saxon-J,并在执行表达式或转换前设置 XML 版本。沿用问题中已有的对象和常量:
processor.getUnderlyingConfiguration().setXMLVersion(XML11);
这里的 XML11 需要按现有 Java 项目的方式导入或引用。
如果还要将包含该字符的结果序列化为 XML,需要同时考虑输出版本:
<xsl:output method="xml" version="1.1"/>
处理器配置和输出版本分别影响字符串处理与序列化。仅设置 xsl:output 的 version="1.1",不能解决此前发生的函数求值错误。Saxon XML 1.1 配置与序列化说明
U+0008 在 XML 1.1 中属于受限字符。写入 XML 文档时必须使用字符引用,例如 ,不能直接写入原始控制字符。XML 1.1 字符规则
只需要在 JavaScript 中生成字符时怎么办?
如果后续处理可以放在 JavaScript 层,可以直接创建该字符:
const backspace = String.fromCodePoint(8);
这会创建实际的 U+0008 字符,但不会改变 Saxon-JS 的 XPath 字符校验规则。如果再将它传回 Saxon-JS,仍需考虑后续操作是否接受它。
哪些修改不能解决这个报错?
- 将样式表声明为
version="3.0":这表示 XSLT 语言版本,不表示启用 XML 1.1。 - 在 XML 1.0 文档中改写为
:字符引用不能让 XML 1.0 禁止的字符变成合法字符。 - 将 XPath 字符串写为
'\u0008':XPath 字符串字面量不采用 JavaScript 的 Unicode 转义语法,得到的是反斜杠及后续字符。
备注:内容仅供参考。
