0

XMLファイルの読み取りに問題があります。以下のxmlを見ると、<fl> ?fl>の代わりに要素が表示されます<fl></fl>。タグの開始と終了の不一致でエラーが発生します。

方法:

  1. <fl> ?fl>の代わりになどのXMLファイルにエラーがあります<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 標準は、準拠していないドキュメントの問題について非常に明確です。1 つの要素の解析エラー (終了タグの欠落など) が原因で、ドキュメント全体が拒否される必要があります。

基本的な問題は次のとおりです。ファイルにエラーが含まれていることを許可すると、文字通り何でも含まれる可能性があります。それを解析する方法はありません。何を「修正」する必要があるかを知る方法は実際にはありません。

なんらかの理由で、入力に非常に具体的で予測可能なエラーがある場合は、それを に渡す前に正規表現で検出できます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 番目の呼び出しにエラー処理を追加しました。

更新 2: 正規表現を更新して、質問者が必要とする正確なケースのみに一致するようにしました (このようなケースでは、誤検出の一致を避けるために、できるだけ具体的にすることが最善です)。

于 2012-10-09T10:30:35.680 に答える