#xml #perl #validation
#xml #perl #проверка
Вопрос:
У меня есть не редактируемый XML-файл, в котором между ними помещено несколько нежелательных тегов, поэтому я получаю исключение при проверке XML-документа с использованием XML::Simple. Это ожидаемо.
my $xml = new XML::Simple();
if (eval { $xml->parse("sample.xml") }) {
print "success!!n";
} else {
print "failed!!!n";
}
Однако анализатор также выдает исключения для амперсандов внутри URL в XML-документе. Ожидаемый результат заключается в том, что амперсанды внутри тела XML не должны вызывать ошибку. Как я могу преодолеть это, используя XML:: Simple или любой другой модуль синтаксического анализа XML? Я попробовал XML:: Simple, XML:: LibXML и XML::Mini::Document. Ни один из них не справился с проблемой амперсанда.
Комментарии:
1. Повторите » Как я могу успешно проверить xml, в котором есть амперсанд внутри любого из тегов xml «, Это недопустимо (если только амперсанд не является частью определенной сущности), так что, похоже, все работает правильно.
2. В дополнение к вашим проблемам с использованием анализатора XML для анализа документа, который не является правильно сформированным XML, вы создаете себе еще одну проблему, используя XML ::Simple. В документации автор модулей говорит «ПОЖАЛУЙСТА, НЕ ИСПОЛЬЗУЙТЕ ЭТОТ МОДУЛЬ В НОВОМ КОДЕ» и «Использование этого модуля в новом коде настоятельно не рекомендуется». Пожалуйста, не игнорируйте его совет.
Ответ №1:
У вас нет XML-файла. Анализатор сообщает вам, что это не XML-файл. Если вы хотите использовать файлы, отличные от XML, не пытайтесь обрабатывать их с помощью инструментов XML.
Если создатель файла утверждал, что это XML, скажите им, что они отправили вам ошибочный файл, и попросите его исправить, или переключитесь на более надежного поставщика. (Что бы вы сделали, если бы загрузили программу, утверждающую, что это Java, и она не скомпилировалась?)
Комментарии:
1. Файл, который я получаю в clearcase vob, имеет расширение .xml, внутри файла есть описание тега с текстом в виде <description>https/blahblah.blah.com/isynch.dll?panel=ModuleConfigamp;Type=ModuleViewamp;Module</description>. Есть ли какой-либо способ, которым я могу это понять??
2. Я не знаю, что такое «clearcase vob», но, несмотря на расширение файла, это не XML, и от него примерно столько же пользы, сколько от автомобиля с удобными сиденьями, четырьмя колесами, блестящей отделкой на фарах и без стартера. Отправьте его обратно и подайте жалобу.
3. @MichaelKay: ClearCase — это система контроля версий, а VOB — это «База версионных объектов», механизм, который он использует для хранения информации о версии.
Ответ №2:
Возможно, вы сможете использовать XML::Liberal, который с радостью примет этот вид неработающего XML. Это также может привести к нарушению вашего XML другими способами, поэтому покупатель остерегается!
Поскольку это подкласс XML:: LibXML, вы могли бы использовать его вместо XML :: LibXML, но я бы этого не стал делать. Вместо этого у меня был бы первый проход, на котором вы конвертируете свой квази-XML в правильный XML (и вы можете это проверить), а затем используете обычные инструменты XML для остальной части вашей обработки (возможно, не XML ::Simple, см. Предупреждение в документах модуля).
Конвертер может быть таким простым, как:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Liberal;
my $parser = XML::Liberal->new('LibXML');
my $doc = $parser->parse_file( 'broken_xml.xml');
print $doc->toString;
Поймите, что это опасное решение, использующее модуль, который находится в альфа-состоянии и к которому не прикасались в течение 6 лет. Таким образом, он определенно не может использоваться как часть производственной системы.
Реальное решение состоит в том, чтобы входные данные были реальным (правильно сформированным) XML. Что возможно, голые amp;
URL-адреса в URL-адресах могут быть заменены либо на amp;amp;
, либо на ;
, но для этого вы должны использовать инструменты HTML, а не XML. Или пристыдите своего провайдера, отправив вам настоящий XML.
Тем временем XML::Liberal может быть частью временного решения.
Комментарии:
1. Повторно » Голые
amp;
URL-адреса в URL-адресах могут быть заменены либо наamp;amp;
, либо на;
, 1) Вы не можете произвольно заменитьamp;
в URL-адресах на;
. CGI.pm (и другие) считают их одинаковыми, но это не является ни стандартным, ни универсальным, даже если вы предполагаете, что все запросы являются данными формы. 2) Возможно, что заменаamp;
наamp;amp;
также не является правильным исправлением (например,amp;foo
могла быть опечатка дляamp;foo;
), так что даже это не гарантировано как правильное исправление. неправильные исправления.
Ответ №3:
Правильная терминология для того, что вы делаете, — это проверка того, правильно сформирован документ (соответствует определению XML-документа), а не того, является ли он допустимым (соответствует определению XML-документа и определению схемы). Вы можете использовать XML:: LibXML::Schema для проверки документов.
Тем не менее, похоже, что ваша проверка работает правильно. То, что вы предоставляете, не является (правильно сформированным) XML, и анализатор сообщает вам об этом.
Это не (правильно сформированный) XML:
<ele url="http://www.example.org/form?foo=baramp;moo=mar"/>
Это должно быть
<ele url="http://www.example.org/form?foo=baramp;amp;moo=mar"/>
Это не (правильно сформированный) XML:
<ele>http://www.example.org/form?foo=baramp;moo=mar</ele>
Это должно быть
<ele>http://www.example.org/form?foo=baramp;amp;moo=mar</ele>
Комментарии:
1. Хорошо, итак, нет модуля Perl XML, с помощью которого я мог бы использовать неявное указание игнорировать, если встречается амперсанд.
2. Такой анализатор будет давать ошибки.
3. Было бы ошибкой, если бы он продавался как анализатор XML. Если бы он продавался как инструмент для исправления неправильно сформированного XML, это было бы другое дело…
4. @Michael Kay, 1) OP запросил анализатор / валидатор XML. 2) В OP ничего не было исправлено. 3) Как бы такой инструмент исправил
amp;foo
? Это пропущенная точка с запятой или неэкранированныйamp;
?5. (1) Они спросили «как я могу», не ограничивая решение, (2) Написание инструментов восстановления — это совершенно другое искусство, чем написание синтаксических анализаторов. Ответ в том, что вы делаете предположения, а затем возникает вопрос о том, насколько разумно высказать свое предположение. Например, вы могли бы принять во внимание, существует ли объект с именем foo на самом деле. Но ключевой вывод заключается в том, что, хотя вы можете восстановить много поврежденных данных таким способом, лучше настаивать на получении чистых данных в первую очередь, а не на необходимости исправлять беспорядок.
Ответ №4:
У меня есть не редактируемый XML-файл
На самом деле, нет. У вас нет XML-файла. У вас есть что-то, что почти, но не совсем, является XML-файлом. Правильно сформированный XML-документ не содержит амперсандов, отличных от тех, которые создают начало объекта (которыми эти не являются). Амперсанд в правильно оформленном XML-документе должен быть закодирован как amp;amp;
.
Я думаю, у вас есть три варианта:
- Вернитесь к источнику этого «не-XML» документа и попросите их прислать вам что-нибудь, что является правильно сформированным XML. Если это поступает от внешнего поставщика, вполне могут существовать контракты, в которых говорится, что они будут предоставлять вам XML. Если это так, они являются нарушением контракта.
- Предварительно проанализируйте документ, чтобы исправить кодировку амперсандов. Это, вероятно, будет хрупким, и я не рекомендую это.
- Используйте что-то вроде XML::Liberal для синтаксического анализа документа. Я не рекомендую это, поскольку, как только вы разрешаете нестандартный XML, это скользкий путь, который приводит к беспорядку, который мы видели в парсерах HTML в 1990-х годах 🙂
Если бы это зависело от меня, я бы определенно выбрал первый вариант.
Комментарии:
1. Да, Дэйв, вы правы, у меня есть этот XML-файл (точнее было бы назвать его файлом с расширением .xml 🙂 ) внутри прозрачного vob-файла, где у меня нет доступа к оформлению заказа / регистрации. Спасибо за ваши комментарии.
2. @Kalesh: Итак, вам нужно отследить файл до его источника. Откуда это взялось? Кто его создал? У кого-нибудь будет возможность исправить это за вас. Вам просто нужно выяснить, кто.