2016-09-14 3 views
2

Каков наиболее простой способ обнаружения XML (с использованием XML :: LibXML/libxml2) или простого ввода текста с помощью Perl (5.18 или выше)?Автоматическое обнаружение ввода XML или обычного текста с файлом и STDIN с помощью Perl

У меня есть программа, которая может принимать текстовый ввод или вход XML, а вход XML может быть в произвольных кодировках. Входные данные либо из файла (ARGV), либо из STDIN. Когда только простой текст считается, следующий код достаточно:

local $/ = undef; 
my $text = <> || die; 

Это позволит получить весь входной файл или STDIN как текст, используя параметры кодирования по умолчанию.

Когда рассматривается только XML, следующий код может использоваться (для файла):

my $parser = XML::LibXML->new(); 
my $xml = $parser->load_xml(location => $ARGV[0]); 

Но что это лучший способ объединить два? Я хочу, чтобы libxml2 сделал первый треск на входе, а затем вернулся к тексту, если он терпит неудачу. Если я передаю IO => * STDIN напрямую, libxml2 будет потреблять вход, который потребуется программе позже, если libxml2 определяет, что вход не является XML.

(Примечание: если libxml2 определяет, что вход какой-то XML, но неправильный формат в некотором роде, то программа должна прекратить вместо отступая.)

+0

http://search.cpan.org/~fitzner/File-LibMagic-0.96/LibMagic.pm – xxfelixxx

+1

Как узнать, содержит ли файл, содержащий '' - это XML-файл или текстовый файл? Это может быть и то, и другое. – nwellnhof

+0

nwellnhof, это хороший момент. Мой ответ заключается в том, что вы разрабатываете код для ответа на вопрос так или иначе. В частности: '' - это XML-файл, потому что XML не должен начинаться с '': Вы можете перейти прямо в первый элемент. Вы также можете иметь знак байтового заказа в качестве первого символа. Более общий момент заключается в том, что я хотел бы, чтобы _libxml2 взял первую трещину на входе, затем вернется к простому тексту, если (разбор libxml2) failed_. На основе некоторых тестов libxml2 также принимает пробелы до и после корневого элемента. –

ответ

0
use XML::LibXML; 

my $schema_file = 'test.xsd'; 
my $document = 'test.xml'; 

my $schema = XML::LibXML::Schema->new(location => $schema_file); 

my $parser = XML::LibXML->new; 
my $doc = $parser->parse_file($document); #Or handle STDIN 

eval { $schema->validate($doc) }; 
if ([email protected]){ 
    #file failed to validate, handle as text below 
} 

В качестве альтернативы можно использовать Text::XML «s is_xml , is_well_formed_xml и создавать условные обозначения на их основе.

+0

Извините, но на самом деле я не ищу. Я не хочу проверять XML; Я ищу, чтобы определить, является ли вход XML (в любой кодировке). Например, он может начинаться с '' Или UTF-8 BOM 0xEF, 0xBB, 0xBF, за которым следует или UTF-16BE с или без спецификации или даже без EBCDIC. Я хочу передать байты из STDIN прямо в libxml2, но если libxml2 говорит, что это не XML, чтобы сохранить байты, чтобы попытаться обработать поток как обычный текст. –

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