0

我一直面临使用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>

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

例如:-

$ 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>
4

2 回答 2

2

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

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

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

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

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

于 2021-06-23T14:28:58.003 回答
1

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'})
于 2021-06-23T14:52:01.027 回答