Почему я получаю дополнительную новую строку в середине символа UTF-8 с XML :: Parser? - PullRequest
2 голосов
/ 25 марта 2010

Я столкнулся с проблемой, связанной с UTF-8, XML и Perl. Следующее самое маленькое кусок кода и данных, чтобы воспроизвести проблему.

Вот файл XML, который необходимо проанализировать:

<?xml version="1.0" encoding="utf-8"?>
<test>
  <words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>
  <words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>
  <words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>

  [<words> .... </words> 148 times repeated]

  <words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>
  <words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>
</test>

Разбор выполняется с помощью этого сценария Perl:

use warnings;
use strict;

use XML::Parser;
use Data::Dump;

my $in_words = 0;

my $xml_parser=new XML::Parser(Style=>'Stream');

$xml_parser->setHandlers (
   Start   => \&start_element,
   End     => \&end_element,
   Char    => \&character_data,
   Default => \&default);

open OUT, '>out.txt'; binmode (OUT, ":utf8");
open XML, 'xml_test.xml' or die;
$xml_parser->parse(*XML);
close XML;
close OUT;


sub start_element {
  my($parseinst, $element, %attributes) = @_;

  if ($element eq 'words') {
    $in_words = 1;
  }
  else {
    $in_words = 0;
  }
}

sub end_element {
  my($parseinst, $element, %attributes) = @_;

  if ($element eq 'words') {
    $in_words = 0;
  }
}

sub default {
  # nothing to see here;
}

sub character_data {
  my($parseinst, $data) = @_;

  if ($in_words) {
    if ($in_words) {
      print OUT "$data\n";
    }
  }
}

Когда скрипт запускается, он создает файл out.txt. Проблема в этом файл в строке 147. 22-й символ (который в utf-8 состоит из \ xd6 \ xb8) разделен между d6 и b8 с новой линией. Этого не должно быть.

Теперь мне интересно, есть ли у кого-то еще эта проблема или она может быть воспроизведена. И почему я получаю эту проблему. Я запускаю этот скрипт в Windows:

C:\temp>perl -v

This is perl, v5.10.0 built for MSWin32-x86-multi-thread
(with 5 registered patches, see perl -V for more detail)

Copyright 1987-2007, Larry Wall

Binary build 1003 [285500] provided by ActiveState http://www.ActiveState.com
Built May 13 2008 16:52:49

Ответы [ 2 ]

2 голосов
/ 25 марта 2010

Что происходит, когда вы открываете входной файл с явной кодировкой UTF-8?

 open XML, '<:utf8', 'xml_test.xml' or die;

Никогда не доверяйте ничего, чтобы получить правильную кодировку, угадывая. Всякий раз, когда вы можете, явно добавьте кодировку самостоятельно.

Кроме того, вы уверены, что ввод правильный? Пройдет ли он валидацию с помощью другого инструмента, такого как xmllint. Я знаю, что XML :: Parser должен ловить подобные вещи, но давайте проверим это.

Кроме того, вы можете поместить проблемный ввод в строку и напечатать его снова без проблем? Что происходит, когда вы удаляете только эту часть XML-файла? Появляется ли та же ошибка для другой записи?

1 голос
/ 25 марта 2010

Я не наблюдаю это с

C:\Temp> perl -v

This is perl, v5.10.1 built for MSWin32-x86-multi-thread
(with 2 registered patches, see perl -V for more detail)

Copyright 1987-2009, Larry Wall

Binary build 1006 [291086] provided by ActiveState http://www.ActiveState.com
Built Aug 24 2009 13:48:26
C:\Temp> perl -MXML::Parser -e "print $XML::Parser::VERSION"
2.36
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...