0

我在读取 XML 文件时遇到问题。如果您查看下面的 xml,您会看到 element<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>
4

1 回答 1

1

没有一般方法可以修复 XML 文件中的错误。您所能做的就是将文件作为无效的 XML 拒绝。 XML::Simple 的错误处理文档解释说:

XML 标准对不合规文档的问题非常明确。解析任何单个元素的错误(例如缺少结束标记)必须导致整个文档被拒绝。

基本问题是这样的:一旦允许文件包含错误,它就可以包含任何内容。没有办法解析它。真的没有办法知道应该“纠正”什么。

如果出于某种原因,您的输入有一个非常具体、可预测的错误,您可以在将其传递给XML::Simple. 只要您知道一些特定的结束标签将有?or?/而不是</,您就可以执行以下操作:

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 ($@)
{
    $xmlfile =~ s/\?\/?(desc|en|es|de|fl)>/<\/$1>/g;
    $data = eval { $xml->XMLin($xmlfile) };
    if ($@) 
    { 
        die "Failed to process the file even after attempting corrections: $@"; 
    }
}

以这种方式使用正则表达式有其危险——您依赖于特定格式的输入 XML。但是,通过首先尝试正常处理文件,至少可以最大限度地减少潜在的损坏。这样,您只会在文件无论如何都会失败的情况下做一些冒险的事情。

XMLIn()更新:为第二次调用添加了错误处理。

更新 2:我更新了正则表达式以仅匹配提问者需要的确切情况(在这种情况下,最好尽可能具体以避免误报匹配)。

于 2012-10-09T10:30:35.680 回答