使用 basex 扩展 unicode 字符解析 html 时出错
Error parsing html with extended unicode characters with basex
我在使用 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 的内部字符串到 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'})
我在使用 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 的内部字符串到 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'})