使用 basex 扩展 unicode 字符解析 html 时出错

Error parsing html with extended unicode characters with basex

我在使用 basex html 解析器解析带有扩展 unicode 字符的 html 时遇到了问题。是否可以让解析器支持特殊字符?

代码:

let $htmlRaw := '<span class="eqn">&#120746; + &#120747; = &#120748;</span>'
let $htmlParsed := html:parse($htmlRaw, map { 'encoding': 'utf-8'})
return (
  'INPUT', 
  $htmlRaw,
  'OUTPUT',
  $htmlParsed
)

输出:

INPUT
<span class="eqn"> +  = </span>
OUTPUT
<html>
  <body>
    <span class="eqn">?? + ?? = ??</span>
  </body>
</html>

该错误似乎与 basex 不支持的 tagsoup 库的 output-encoding 参数有关。

例如:-

$ echo "<span class="eqn">&#120746; + &#120747; = &#120748;</span>" | java -jar tagsoup-1.2.1.jar --html

<html><body><span class="eqn">&#55349;&#57258; + &#55349;&#57259; = &#55349;&#57260;</span>
</body></html>

$ echo "<span class="eqn">&#120746; + &#120747; = &#120748;</span>" | java -jar tagsoup-1.2.1.jar --html --output-encoding=utf-16
<html><body><span class="eqn"> +  = </span>
</body></html>

如果我在 BaseX 的 HtmlParser.java (https://github.com/martin-honnen/basex/commit/4711a390e4069d363243f48c95456544916f40f7) 中将 opt(writer, "encoding", Strings.UTF8); 添加为第 156 行,问题似乎就会消失。但是,我不确定这是修复它的正确方法。

问题的根源似乎是两个问题,TagSoup 在没有将 XMLWriter 的输出编码设置为任何 Unicode 编码(如 UTF-8 或 UTF-16)的情况下,输出两个数字字符引用,表示外部的 Unicode 字符BMP 的。

因此您必须将 UTF-8 或 UTF-16 设置为 TagSoup 的 XMLWriter 的输出编码,然后它会切换到 Unicode 模式并只输出字符而不是字符引用,TagSoup 的 XMLWriter 似乎可以提供这两种编码StringWriter BaseX 设置的正确字符。

此外,BaseX 的内部字符串到 byte[] 的转换似乎需要 UTF-8 编码的字符串,不确定为什么在 Java 平台上会出现这种情况,但是 token 函数委托工作utf8 函数。

因此,HtmlParser 中的修复似乎是设置 opt(writer, "encoding", Strings.UTF8)

Martin Honnen 的回答很好地描述了这个问题。包含错误修复的新快照可用 (https://files.basex.org/releases/latest/)。

如果您将 HTML 输入作为字符串传递,它已经以 UTF-8 编码;但如果您有二进制输入,encoding 选项会很有帮助:

let $data := file:read-binary('my.html')
return html:parse($data, map { 'encoding': 'CP1252'})