-1

Perl で解析して別の形式に出力する必要がある複雑なマルチレジスタ ドキュメント xml があります。

入力 XML:

    <?xml version="1.0" encoding="UTF-8"?>
     <response>
     <result name="response" numFound="58582" start="0"> 
     <doc>
        <str name="body">Have a great time at this park!</str><int name="is_park_id">317851</int><str name="ss_image_thumb_small"/>
    <str name="title">Playground</str>    
     </doc>
     <doc>
<str name="body">Have a great time at this park!</str><int name="is_park_id">317851</int><str name="ss_image_thumb_small"/>
    <str name="title">Playground</str>    
     </doc>
     </result>
     </response> 

必要な出力形式は次のとおりです。

    <?xml version="1.0" encoding="iso-8859-1"?>
     <Feed>
     <Products>
     <Product>
<Description>Have a great time at this park!</Description><ExternalId>PF317851</ExternalId><ImageUrl/>
     <Name>Playground</Name>
</Product>
<Product>
<Description>Have a great time at this park!</Description><ExternalId>PF317851</ExternalId><ImageUrl/>
     <Name>Playground</Name>
</Product>
     </Products>
     </Feed>

<str name="body">は説明として扱われる<int name="is_park_id">べきであり、 として扱われるべきで<ExternalId>あり、 として扱わ<str name="title">れるべき<Name>です。

XML を新しい形式にフォーマットするのを手伝ってもらえますか?

4

4 に答える 4

1

あなたのファイルで XML::Simple を試しました。これが私のプログラムです:

#! /usr/bin/env perl
#

use strict;
use warnings;
use feature qw(say);

use XML::Simple;
use Data::Dumper;

my $xml_ref = XMLin("test.xml");

say Dumper $xml_ref;

出力は次のとおりです。

VAR1 = {
          'result' => {
                      'name' => 'response',
                      'doc' => {
                               'int' => {
                                        'content' => '317851',
                                        'name' => 'is_park_id'
                                      },
                               'str' => {
                                        'body' => {
                                                  'content' => 'Have a great time at this park!'
                                                },
                                        'ss_image_thumb_small' => {},
                                        'title' => {
                                                   'content' => 'Playground'
                                                 }
                                      }
                             },
                      'numFound' => '58582',
                      'start' => '0'
                    }
        };

XML ファイルを完全に解析します。

Perl のリファレンスと、Perl でハッシュをハッシュする方法を理解していますか? それはあなたの問題かもしれません。

于 2013-01-11T19:37:36.930 に答える
0

どうぞ:

#!/usr/bin/env perl
use 5.010;
use strict;
use warnings qw(all);

use Data::DPath qw(dpath);
use File::Slurp;
use XML::Hash::LX;

# parse XML and store as a nested Perl hash
my $xml = xml2hash(read_file('input.xml'));

# from/to key mapping
my $from_to = {
    body                => 'Description',
    is_park_id          => 'ExternalId',
    ss_image_thumb_small=> 'ImageUrl',
    title               => 'Name',
};

# translate one bucket
my %result =
    map {
        $from_to->{$_} => (
            $xml ~~
            dpath qq(//*[key eq "-name" and value eq "$_"]/../#text)
        )->[0] // ''
    } keys %$from_to;

# output new XML
say hash2xml({
    Feed => {
        Products => {
            Product => \%result,
        },
    },
});

ただし、XPathを使用する方が適切です。

于 2013-01-11T19:38:40.287 に答える
0

私はperlのすべてのXMLニーズにXML::LibXMLを使用しています。

use XML::LibXML;

my @records;

# parse input

{
    my $dom = XML::LibXML->load_xml( location => 'input.xml' );

    my $root_node = $dom->documentElement;  # <response> tag

    for my $doc_node ( $root_node->getChildrenByTagName('doc') ) {

        my $record = {};    

        for my $node ( $doc_node->childNodes ) {
            $record{name} = $node->getAttribute('name');
            $record{value} = $node->textContent;
        }

        push @records, $record;
    }
}

# create output

{
    my $dom = XML::LibXML::Document->new('1.0',$some_encoding);

    my $root_node = $doc->createElement('Feed');

    my $products_node = $root_node->createElement('Products');

    for my $record ( @records ) {

        my $pnode = $products_node->createElement('Product');

        my $dnode = $pnode->createElement('Description');

        $dnode->appendText( $record->{body} );

        my $nnode = $pnode->createElement('Name');

        $nnode->appendText( $record->{name} );

        # ...

    }


    print $dom->toString;
}
于 2013-01-11T19:44:04.117 に答える
0

XML::SAX/XML::Simple バージョンは次のとおりです。

#!/usr/bin/env perl
package XML::SAX::Handler::Parks;
use strict;
use warnings qw(all);

use base qw(XML::SAX::Base);

sub new {
    return bless {
        data    => '',
        from_to => {
            body                => 'Description',
            is_park_id          => 'ExternalId',
            ss_image_thumb_small=> 'ImageUrl',
            title               => 'Name',
        },
        product => {},
        products=> [],
        this    => '',
    } => __PACKAGE__;
}

sub start_element {
    my ($self, $el) = @_;
    $self->{data} = '';
    if ($el->{Name} =~ /^(?:int|str)$/x) {
        while (my (undef, $attr) = each %{$el->{Attributes}}) {
            if ($attr->{Name} eq 'name') {
                $self->{this} = $attr->{Value};
            }
        }
    }
    return;
}

sub end_element {
    my ($self, $el) = @_;
    my $key = $self->{from_to}{$self->{this}};
    $self->{product}{$key} = $self->{data};
    if ($el->{Name} eq 'doc') {
        push @{$self->{products}}, { %{$self->{product}} };
        $self->{product} = {};
    }
    return;
}

sub characters {
    my ($self, $data) = @_;
    $self->{data} .= $data->{Data};
    return;
}

1;

package main;
use strict;
use warnings qw(all);

use XML::Simple;
use XML::SAX::PurePerl;

my $handler = XML::SAX::Handler::Parks->new;
my $parser = XML::SAX::PurePerl->new(Handler => $handler);

$parser->parse_file(\*DATA);

print XMLout(
    {
        Products => {
            Product => $handler->{products},
        },
    },
    KeyAttr     => [],
    NoAttr      => 1,
    RootName    => 'Feed',
    XMLDecl     => 1,
);

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<response>
  <result name="response" numFound="58582" start="0">
    <doc>
      <str name="body">Have a great time at this park!</str>
      <int name="is_park_id">317851</int>
      <str name="ss_image_thumb_small"/>
      <str name="title">Playground</str>
    </doc>
    <doc>
      <str name="body">hello world</str>
      <int name="is_park_id">12345</int>
      <str name="ss_image_thumb_small"/>
      <str name="title">Park</str>
    </doc>
  </result>
</response>
于 2013-01-11T21:41:55.270 に答える