问题描述
我在使用 basex html 解析器解析带有扩展 unicode 字符的 html 时遇到了问题。是否可以让解析器支持特殊字符?
代码:
let $htmlRaw := '<span class="eqn">𝞪 + 𝞫 = 𝞬</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">𝞪 + 𝞫 = 𝞬</span>" | java -jar tagsoup-1.2.1.jar --html
<html><body><span class="eqn">�� + �� = ��</span>
</body></html>
$ echo "<span class="eqn">𝞪 + 𝞫 = 𝞬</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 的内部 String 到 byte[] 转换似乎需要 UTF-8 编码的字符串,不确定为什么在 Java 平台上会出现这种情况,但 token
函数将工作委托给 {{1} } 函数。
这样,HtmlParser 中的修复方法似乎是设置 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'})