2012-10-09 133 views
0

我在讀取XML文件時遇到問題。如果你看下面的xml,你會看到元素<fl> ?fl>而不是<fl></fl>。我收到錯誤打開和結束標記不匹配。解析器錯誤:開始和結束標記不匹配:

如何:

  1. 有在XML文件中,如<fl> ?fl>而不是<fl></fl>的錯誤。如何忽略這樣的錯誤,或者在讀取xml時修復它們並將其用於解析?
  2. 我只想讀$_->{desc}->[0]->{en}->[0]的內容,而不是<de>,<es>,<fl>

現在我在讀XML文件,如:

package test::test6382_sunseekingeurope; 
use strict; 
use warnings; 
use test; 
use base qw/test/; 
use URI::URL; 
use XML::Simple; 
use Data::Dumper; 
use constant TASK_ID => 6382; 
use constant CR_TYPE => '6382'; 
use constant IMAGE_PATH => "/home/testco/public_html/files/";#"images/"; 

sub new 
{ 
my $class = shift; 
my $self = $class->SUPER::new(CR_TYPE, TASK_ID); 
bless $self, $class; 

my $url = 'http://www.onbip.com/xml/sunseeking9.xml'; 

my $xml = $self->geturl('url'=>$url); 
$self->extract($xml); 
} 

sub extract{ 
my $self = shift; 
my $xmlfile = shift; 
my $xml = new XML::Simple(ForceArray=>1,'KeyAttr' =>'image'); 
my $data = $xml->XMLin($xmlfile); 

foreach(@{$data->{property}}){ 
    my $property = &makeScalar($_->ID->[0]); 
    my $description = &makeScalar($_->{desc}->[0]->{en}->[0]); 

XML:

<property> 
<id>226887</id> 
<desc> 
<en> 
    Nice house in the center of Alhaurin de la Torre with walking distance to all amenities. 
</en> 
<es> 
    Bonita casa mata en Alhaurin de la Torre con vistas a la montana, se puede acceder caminando al centro, colegios, etc. 
</es> 
    <de> 
    guter zustand, bezaubernde immobilie, 
    </de> 
    <fl> 
    bon n acces par la route, partiellement meubl?a proximit?'?les, partiellement r?v 
    ?fl> 
</desc> 
</property> 
+1

請,下次使用正確格式化。 – choroba

+0

告訴你的代碼不能讀取XML,它只能通過Perl數據結構散步。我猜你是使用一個模塊用於解析XML,但是你有什麼顯然不是XML ... – pmakholm

回答

0

有在一個XML文件來修復錯誤時不一般的方式。你所能做的就是拒絕該文件爲無效的XML。 The error handling documentation for XML::Simple解釋說:

XML標準是對不符合 文件的問題非常清楚。解析任何單個元素時出錯(例如 缺少結束標記)必須導致整個文檔被拒絕。

基本的問題是:一旦你允許一個文件包含錯誤,它可以包含字面上的任何東西。沒有辦法解析。真的沒有辦法知道應該「糾正」什麼。

如果出於某種原因,你的投入有非常具體的,可預見的錯誤,你可以將它傳遞給XML::Simple前檢測與一個正則表達式。只要你知道一些具體的關閉標籤將有</??/相反,你可以做這樣的事情:

my $xmlfile = shift; 

my $xml = new XML::Simple(ForceArray=>1,'KeyAttr' =>'image'); 

#Try it to parse the file as is first. 
my $data = eval { $xml->XMLin($xmlfile) }; 

#On error, try fixing. 
if ([email protected]) 
{ 
    $xmlfile =~ s/\?\/?(desc|en|es|de|fl)>/<\/$1>/g; 
    $data = eval { $xml->XMLin($xmlfile) }; 
    if ([email protected]) 
    { 
     die "Failed to process the file even after attempting corrections: [email protected]"; 
    } 
} 

以這種方式使用正則表達式有其危險性 - 你是依靠輸入XML格式爲特定格式。但是,通過首先嚐試正常處理文件,潛在的破壞至少會被最小化。這樣,在文件失敗的情況下,你只會做一些冒險的事情。

更新:添加錯誤處理到第二個XMLIn()調用。

更新2:我更新了正則表達式以僅匹配提問者所需的確切情況(在這種情況下,最好儘可能具體以避免錯誤匹配)。

+0

如何更換?/ FL>在$ XMLFILE =〜S/\?(\ W +>)/ <\/$ 1 /G; 並使用這兩個正則表達式? – user1059749

+0

該單個正則表達式將修復任一'/ FL>'或'FL>':?'$ XMLFILE =〜S/\ \ /?(\ w +>)/ <\/$ 1/g;'但是,要小心:如果存在多種簡單的可預測錯誤,這個問題會變得非常混亂!您需要確保您確切知道您的輸入格式可能是什麼,並且您已經處理了所有可能的情況。如果你不能這樣做,那麼你可能不應該使用這個正則表達式。 – dan1111

+0

我只有在XML錯誤,這個元素: - > user1059749

相關問題