2012-10-09 95 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

相关问题