2011-01-12 3 views
3

У меня есть xml с тегом кодирования, установленным в 'utf-8'. Но на самом деле это iso-8859-1.Исправление кодировки XML

Программно, как определить это в perl и python? и как мне декодировать с другим кодированием?

В Perl'е, я попытался

$xml = decode('iso-8859-1',$file) 

, но это не работает.

+1

У вас есть образец XML-файла, который вы не можете проанализировать? Я начинаю запутываться между объявленной кодировкой и «на самом деле». –

ответ

4

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

В Perl проще всего попытаться декодировать его как utf-8 и проверить наличие сбоев. (Работает только этот окольный путь, в кодировке UTF-8 кодируются западным язык документа почти всегда является действительным изо-8859-1 документ, а)

my $xml = eval { decode_utf8($file, FB_CROAK) }; 
if ([email protected]) { is_probably_iso-8859-1_instead } 

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

Если нет объявления XML или MIME-типа, будет использоваться внутренняя кодировка Perl, поэтому код, который вы скопировали, должен сделать трюк.

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

# assuming it's on line 1: 
$contents =~ s/.*/<?xml version="1.0" encoding="ISO-8859-1"?>/; 
+0

Спасибо JB. Я использую simpleXML для perl.Он не декодируется, когда я использую вышеуказанный код, когда для кодировки установлено значение utf-8. Есть предположения? – vkris

+0

Никогда не слышал об этом, и, похоже, его легко путать с библиотекой PHP. У вас есть прямая связь? –

+0

(1) о «закодированном на западном языке документе utf-8 почти всегда действительный iso-8859-1» ... на самом деле ** любой файл ** (любой язык, любая кодировка) может быть «успешно», (но не часто значимо) декодируется как iso-8859-1. (2) Если XML-декларация отсутствует, анализатор должен использовать UTF-8. Все остальное противоречит спецификации XML. –

1

Общая процедура должна быть такой же, независимо от того, какой язык:

Открыть файл, прочитать исходные байты в строку.

Попытка декодирования raw_bytes как UTF-8 с опцией, которая проверяет наличие ошибок или вызывает исключение, если оно недопустимо UTF-8.

Вероятность того, что файл значимого текста Юникода разумной длины, успешно закодированный как ISO-8859-1, пройдет, этот тест UTF-8 очень низок (если, конечно, это ASCII, который является подмножеством как ISO-8859- 1 и UTF-8).

Если тест не удался, отмените объявление XML, если оно существует. PREPEND это:

<?xml version="1.0" encoding="ISO-8859-1"?> 

Кстати, вы уверены, что на самом деле имеют ISO-8859-1 данные, а не данные CP1252 (от платформы операционной системы Windows)?

+0

Код perl/python смог прочитать, когда я изменил кодировку на iso-8859-1. Его linux, так что я могу подтвердить, что это не CP1252? – vkris

+0

btw, правильно сказано. У меня есть 2 варианта. 1. Изменить кодировку xml. Я использую (http://code.google.com/p/java-xmlbuilder/), в котором я не знаю, как изменить кодировку. 2. Мне нужно декодировать неправильно закодированный xml по ISO-8859-1. Который я пытаюсь использовать декодирование (в perl) – vkris

1

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

Кроме того, главное, чтобы ваш файл не был XML, поэтому вы не можете исправить его с помощью инструментов XML. Вам нужно атаковать его на уровне персонажа или двоичного кода. Как говорили другие, шаг 1 состоит в том, чтобы обнаружить, что он недействителен UTF-8; шаг 2 - удалить неверную декларацию XML и заменить ее на правильную. Ни один из них не должен быть особенно сложным.

Смежные вопросы