1

XMLデータを保存する必要があります

<pathway name="path:ko00010" org="ko" number="00010"
             title="Glycolysis / Gluconeogenesis"
             image="http://www.kegg.jp/kegg/pathway/ko/ko00010.png"
             link="http://www.kegg.jp/kegg-bin/show_pathway?ko00010">
        <entry id="13" name="ko:K01623 ko:K01624 ko:K01622 ko:K11645 ko:K16305 ko:K16306" type="ortholog" reaction="rn:R01070"
            link="http://www.kegg.jp/dbget-bin/www_bget?K01623+K01624+K01622+K11645+K16305+K16306">
            <graphics name="K01623..." fgcolor="#000000" bgcolor="#BFBFFF"
                 type="rectangle" x="483" y="404" width="46" height="17"/>
        </entry>
 </pathway>

さらに使用するためにデータ構造に変換します。ハッシュと配列のような DS, これは私のコードです

#!/usr/bin/perl                                                                                                                                                                                                                                                                                                                                                             

use XML::LibXML;
use strict;
use warnings;
my $parser = new XML::LibXML;

my $xmlp= $parser -> parse_file("ko00010.xml");
my $rootel = $xmlp -> getDocumentElement();

my $elname = $rootel -> getName();
my @rootelements=$rootel -> getAttributes();


foreach my $rootatt(@rootelements){
    my  $name = $rootatt -> getName();
    my $value = $rootatt -> getValue();
    print " ${name}[$value]\n ";
}

my @kids = $rootel -> childNodes();
foreach my $child(@kids) {
    my $elname = $child -> getName();
    my @atts = $child -> getAttributes();
    foreach my $at (@atts) {
        my $name = $at -> getName();
        my $value = $at -> getValue();
        print " ${name}[$value]\n ";

    }
}

これまでのところ、Graphics ノードとその子を除くすべての要素にアクセスできます

4

4 に答える 4

6

別のまったく異なるアプローチ: XML スキーマを使用し、XML データの自動変換にCPAN モジュールXML::Compileを使用します。のような他の xml-to-data ツールとは対照的に、は推測したり、"ForceArray" のようなオプションで微調整したりする必要はありません。XML::SimpleXML::Compile

データの XML スキーマがない場合は、次を使用して自動的に作成できますtrang

trang testdata.xml schema.xsd

XML::Compilexml2yamlクイック変換用のコマンドライン ツールが付属しています。

xml2yaml testdata.xml schema.xsd > testdata.yaml
于 2013-07-18T12:13:26.520 に答える
2

どのデータ構造を正確に作成したいのか、私にはわかりません。または、XPath を使用して必要なデータを取得でき、XML を別のものにマップする必要がないのに、なぜデータ構造を作成する必要があるのか​​。

XML::Simpleの動作をエミュレートしようとしているように見えます。この場合、XML::Simple を直接使用しないでください。複雑な XML に対して一般的に推奨されていないことはわかっていますが、XML が単純で、XML::Simple によって作成されたデータが機能する場合は、書き直そうとするよりも、広く使用されているモジュールを使用する方がおそらく安全です。 (知っておくべきことは、XML::Twig で書き直したということです。特に難しいことではありませんが、必ずしも完全に些細なことでもありません)。

于 2013-07-18T13:23:00.093 に答える
1

あなたがする必要があります

my @grand_kids = $child -> childNodes();

2番目の foreach 内で、属性を介して別のステップを実行します

私はあなたのために例を作りました

#!/usr/bin/perl     
use XML::LibXML;
use strict;
use warnings;
my $parser = new XML::LibXML;

my $xmlp= $parser->parse_file("ko00010.xml");
my $rootel = $xmlp->getDocumentElement();

my $elname = $rootel->getName();
my @rootelements=$rootel->getAttributes();

foreach my $rootatt(@rootelements){
    printf "R {%s}[%s]\t", $rootatt->getName(), $rootatt->getValue();
}

my @kids = $rootel -> childNodes();
foreach my $child(@kids) {
    printf "\nCH = %s\n",  $child->getName();
    my @atts = $child->getAttributes();
    foreach my $at (@atts) {
        printf "C {%s}[%s]\t", $at->getName(), $at->getValue();
    }
    my @grand_kids=$child->childNodes();
    foreach my $grand_child(@grand_kids) {
        printf "\nGR CH = %s\n",  $grand_child->getName();
        my @atts2 = $grand_child->getAttributes();
        foreach my $at2 (@atts2) {
            printf "GC {%s}[%s]\t", $at2->getName(), $at2->getValue();
        }
    }
}

この出力を与える-(#textノードがどこから来ているのかわかりません)

R {name}[path:ko00010]  R {org}[ko] R {number}[00010]   R {title}[Glycolysis / Gluconeogenesis] R {image}[http://www.kegg.jp/kegg/pathway/ko/ko00010.png]   R {link}[http://www.kegg.jp/kegg-bin/show_pathway?ko00010]  
CH = #text

CH = entry
C {id}[13]  C {name}[ko:K01623 ko:K01624 ko:K01622 ko:K11645 ko:K16305 ko:K16306]   C {type}[ortholog]  C {reaction}[rn:R01070] C {link}[http://www.kegg.jp/dbget-bin/www_bget?K01623+K01624+K01622+K11645+K16305+K16306]   
GR CH = #text

GR CH = graphics
GC {name}[K01623...]    GC {fgcolor}[#000000]   GC {bgcolor}[#BFBFFF]   GC {type}[rectangle]    GC {x}[483] GC {y}[404] GC {width}[46]  GC {height}[17] 
GR CH = #text

CH = #text
于 2013-07-18T11:56:32.653 に答える
0

XML::Simple も機能しますが、LibXML を使用することもお勧めします。これは、いくつかの顕著な違いと XML::Simple から LibXML への変換に関するperlmonks の記事です。

XPathContextfindnodesを使用して LibXML を使用してそれを行う 1 つの方法:

use strict;
use warnings;
use XML::LibXML;
use Data::Dumper;

my $parser    = XML::LibXML->new();
my $doc       = $parser->parse_file("ko00010.xml");
my $root      = $doc->getDocumentElement();
my %nodeHash  = ();

# get list of nodes and stores each nodeName(key) and textContent(value) in %nodeHash
my $perlmatch = sub {
    die "Not a nodelist"
      unless $_[0]->isa('XML::LibXML::NodeList');
    die "Missing a regular expression"
      unless defined $_[1];
    my $i = 0;
    while ( my $node = $_[0]->get_node($i++) ) {
        push @{ $nodeHash{$node->nodeName} }, $node->textContent; 
    }
};

# Create XPathContext and find all nodes
my $xc = XML::LibXML::XPathContext->new($root);
$xc->registerFunction( 'perlmatch', $perlmatch ); # register 'perlmatch' function   
$xc->findnodes('perlmatch(//*, ".")') or die "Error retrieving nodes."; # //* is to go through all parent and child nodes, "." to match any nodeName

print Dumper(%nodeHash); # print the contents of nodeHash (you can see the final hash structure here)

CPAN XML::LibXML::XPathの例から抜粋(配列の代わりにハッシュに置き換え、すべてのノードを "." に置き換えます)。

于 2014-07-28T15:26:44.987 に答える