2016-09-14 43 views
2

什麼是檢測XML最佩爾利方式(使用XML ::的libxml/libxml2的)或純文本輸入用Perl(5.18或更高版本)?自動檢測XML或純文本輸入與文件和標準輸入用Perl

我有一個程序,可以接受純文本輸入或XML輸入和XML輸入可以是任意編碼。輸入來自文件(ARGV)或STDIN。當只有純文本被認爲是,下面的代碼就足夠了:

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

這將讓整個輸入文件或標準輸入文本,使用默認的編碼設置。

當只有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的解析)fails_。根據一些測試,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::XMLis_xmlis_well_formed_xml方法並基於這些創建條件。

+0

對不起,但實際上我沒有找到。我不想驗證XML;我期待確定輸入是否爲XML(以任何編碼方式)。例如,它可以以<?xml version =「1.0」?>',或UTF-8 BOM 0xEF,0xBB,0xBF後跟或帶或不帶BOM的UTF-16BE甚至EBCDIC開頭。我想從交付標準輸入字節直接libxml2的,但這時如果libxml2的說,這是不是XML,以保持字節嘗試處理流爲純文本。 –