【问题标题】:Improper UTF-8 and LibXML::Reader不正确的 UTF-8 和 LibXML::Reader
【发布时间】:2016-12-14 08:42:56
【问题描述】:

我有一个来自远程源的大型 XML 文件,上面写着“UTF8”,文件显示 us-ascii。

<?xml version="1.0" encoding="utf-8"?>...

file -bi <file> indicates application/xml; charset=us-ascii
Encode::Guess indicates UTF8

编辑:还有一些读取文件的代码,最初是从 LWP 获取的输出...我也尝试在此处强制进行一些编码,但会出现其他错误,例如宽字符。

my $fh = IO::File->new;
$fh->open( '<' . $filename )
$content = join '', <$fh>;

我正在使用 XML::Reader

my $reader = XML::LibXML::Reader->new(string => $content) or die qq(cannot read content: $!);

while ($reader->nextElement($template->{ 'item' } )) {
    my $copy = $reader->copyCurrentNode(1);
    my $test = $copy->findvalue( 'description' )
...# do other stuff with $copy

这在大多数内容中都可以正常工作。但是,似乎有一些无效的 utf-8 或格式错误的数据,因为它在中途给出了错误..
(注意,在 XML::Bare 中,整个 xml 被处理得“很好”,因为它更宽容,但是文件受到内存大小的限制,所以我需要一个更小的内存 xml 解析器)。

Entity: line 64070: parser error : Input is not proper UTF-8, indicate encoding !
Bytes: 0x1A 0x73 0x20 0x73

如果我在上次成功后的时间点查看 vim,我可以看到

^Z  or <^Z>  26,  Hex 1a,  Octal 032 with :ascii in vim

我已查看 here on SO 以尝试确保至少有效的 UTF-8,因为我无法修复原点,并且正在尝试...

use Encode qw( encode decode );
my $octets = decode('UTF-8', $content, Encode::FB_DEFAULT );
$content = encode('UTF-8', $octets, Encode::FB_CROAK );

但我仍然遇到同样的错误。我很高兴跳过任何带有无效 UTF-8 的部分,但是整个解析器都死了,而且我看不到任何以后继续处理的方法(我相信这应该发生在 XML 解析中)。

我的问题是,这是保证 UTF-8 的最佳方式(假设我无法更改文件),还是有一种方法可以解决该错误(我可能会将那个特定的字符正则表达式,但我假设以后可能会有其他类似的问题,所以感觉很笨拙)?

【问题讨论】:

  • 通常我会期望像XML::LibXML::Reader-&gt;new(location =&gt; "http://example.com/file.xml") 这样的代码,然后XML 解析器会根据需要负责解析和解码。如果您从带有new(string =&gt; $content) 的字符串加载,当您收到有关不正确 UTF-8 的错误时,您在哪里/如何创建该字符串?
  • 我刚刚在顶部附近添加了一个编辑。
  • 提示:open(my $fh, '&lt;:raw', $qfn) or die $!; 会更好,因为它可以确保文件是“二进制”。
  • 提示:XML::LibXML::Reader-&gt;new(IO =&gt; $fh) 比将整个文件加载到内存中更有意义。
  • 谢谢 ikegami,有一个不同的过程可以加载文件,这就是为什么会这样,但我会看看我们是否可以稍微改变一下,因为减少内存会很有价值。我还将查看加载为二进制文件。非常有用。

标签: xml perl utf-8


【解决方案1】:

错误信息具有误导性;该问题与编码无关[1]。事实上,我收到的错误如下[2]

:1: parser error : PCDATA invalid Char value 26

来自 XML 规范,

Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

U+001A 不能合法地出现在 XML 文件中,甚至不能作为字符引用 (&amp;#x1A;)。

使用字符引用 must 引用的字符与 Char 的产生式相匹配。

如果文件包含二进制数据,则二进制部分应进行编码(例如使用 base64)。


  1. 1A2073都小于80

  2. 我使用 XML::LibXML 而不是 XML::LibXML::Reader 进行了测试,但我怀疑相关差异实际上是 XML::LibXML 或 libxml2 的版本不同。

    李>

【讨论】:

  • 谢谢,这让我现在找到了正确的方向,查看了有效的 xml。
猜你喜欢
  • 2016-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
  • 2019-05-23
相关资源
最近更新 更多