无法访问所有XML元素PERL [英] Cannot access all XML elements PERL
问题描述
我有一个简单的Perl脚本,它可以从一台服务器解析下载的XML文件。唯一的问题是,我已经做了数组似乎只存储第一组的标签。
I have a simple Perl script which can parse a downloaded XML file from a server. The only problem is that the array I have made only seems to store the first set of tags.
下面是我的code:
sub test_button_func() {
$ua->cookie_jar($cookie_jar);
# Now make your request
my $server_endpoint = "server_url_link";
$server_endpoint =~ s/\%id\%/$user/g;
# set custom HTTP request header fields
my $req = HTTP::Request->new(GET => $server_endpoint);
$req->header('content-type' => 'application/json');
my $parser = shift;
my $resp = $ua->request($req);
if ($resp->is_success) {
# XML response received from Jazz API.
my $message = $resp->decoded_content;
# Parse the XML downloaded here:
# create object
my $xml = new XML::Simple;
# Read XML file
my @data = $xml->XMLin($message);
my $arraySize = scalar (@data);
# Print out the data we need
for (my $num = 0; $num <= ($arraySize - 1); $num++) {
print @data[0]->{'oslc_disc:entry'}[$num]{'oslc_disc:ServiceProvider'}{'dc:title'};
print "\n";
}
}
else {
print "HTTP GET error code: ", $resp->code, "\n";
print "HTTP GET error message: ", $resp->message, "\n";
print $resp->decoded_content;
}
}
我试图解析XML是这样的:
The XML I am try to parse is this:
<oslc_disc:entry>
<oslc_disc:ServiceProvider>
<dc:title>URL MAIN TITLE</dc:title>
<oslc_disc:details rdf:resource="URL LINK"/>
<oslc_disc:services rdf:resource="URL LINK"/>
<jfs_proc:consumerRegistry rdf:resource="URL LINK"/>
</oslc_disc:ServiceProvider>
</oslc_disc:entry>
所以我的观点是,我可以分析的第一oslc_disc条目。但有比在XML文件中的一个更多。我如何解析的休息吗?
So my point is that I can parse the very first "oslc_disc" entry. But there is much more than one of those in the XML file. How do I parse the rest?
推荐答案
不要使用XML库来解析RDF。这将导致你痛苦的世界。
另外,不要使用XML ::简单的什么,直到永远。
Also, don't use XML::Simple for anything, ever.
RDF ::特里尼是在本领域RDF在Perl的当前状态。 Attean 的正在写入来取代它,是重量更轻,并应提供一个更好的API,而不是真正的准备好了没有。
RDF::Trine is the current state of the art for RDF in Perl. Attean is being written to replace it, is lighter weight, and should offer a nicer API, but is not really ready yet.
use strict;
use warnings;
use RDF::Trine;
# $base is for resolving any relative URLs.
my $base = 'http://example.com/';
# Parse the data into $model
my $parser = RDF::Trine::Parser::RDFXML->new;
my $model = RDF::Trine::Model->new;
$parser->parse_file_into_model($base, \*DATA, $model);
# Some namespaces for querying the data...
my $oslc = RDF::Trine::Namespace->new('http://open-services.net/xmlns/discovery/1.0/');
my $dc = RDF::Trine::Namespace->new('http://purl.org/dc/terms/');
# Cycle through the objects of oscl_disc:entry
for my $provider ( $model->objects(undef, $oslc->entry) ) {
# Get the title. This returns a list of titles, so we call
# it in list context and get just the first result.
my ($title) = $model->objects($provider, $dc->title);
# Print it.
print "GOT: ", $title->literal_value, "\n";
}
__DATA__
<oslc_disc:ServiceProviderCatalog
xmlns:oslc_disc="http://open-services.net/xmlns/discovery/1.0/"
xmlns:dc="http://purl.org/dc/terms/"
xmlns:jfs_proc="https://jazz.net/xmlns/prod/jazz/process/1.0/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
rdf:about="https://localhost:9443/ccm/oslc-scm/catalog.xml"
>
<oslc_disc:entry>
<oslc_disc:ServiceProvider>
<dc:title>Foo Bar Baz</dc:title>
<oslc_disc:details rdf:resource="foo"/>
<oslc_disc:services rdf:resource="bar"/>
<jfs_proc:consumerRegistry rdf:resource="baz"/>
</oslc_disc:ServiceProvider>
</oslc_disc:entry>
<oslc_disc:entry>
<oslc_disc:ServiceProvider dc:title="Foo Bar Baz II">
<oslc_disc:details rdf:resource="foo2"/>
<oslc_disc:services rdf:resource="bar2"/>
<jfs_proc:consumerRegistry rdf:resource="baz2"/>
</oslc_disc:ServiceProvider>
</oslc_disc:entry>
</oslc_disc:ServiceProviderCatalog>
使用
例Attean
我没有用太多Attean还,所以有可能是这样做的更优雅的方式...
Example using Attean
I've not used Attean much yet, so there may be more elegant ways of doing this...
use strict;
use warnings;
use Attean::RDF qw(iri);
# $base is for resolving any relative URLs.
my $base = 'http://example.com/';
# Parse the data into $model
my $store = Attean->get_store('Memory')->new;
my $model = Attean::MutableQuadModel->new( store => $store );
my $data = do { local $/; <DATA> }; # slurp filehandle into string
$model->load_triples(RDFXML => iri($base), $data);
# Some namespaces for querying the data...
my $oslc = 'http://open-services.net/xmlns/discovery/1.0/';
my $dc = 'http://purl.org/dc/terms/';
# Cycle through the objects of oscl_disc:entry
for my $provider ( $model->objects(undef, iri("${oslc}entry"))->elements ) {
# Get the title. This returns a list of titles, so we call
# it in list context and get just the first result.
my ($title) = $model->objects($provider, iri("${dc}title"))->elements;
# Print it.
print "GOT: ", $title->value, "\n";
}
__DATA__
<oslc_disc:ServiceProviderCatalog
xmlns:oslc_disc="http://open-services.net/xmlns/discovery/1.0/"
xmlns:dc="http://purl.org/dc/terms/"
xmlns:jfs_proc="https://jazz.net/xmlns/prod/jazz/process/1.0/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
rdf:about="https://localhost:9443/ccm/oslc-scm/catalog.xml"
>
<oslc_disc:entry>
<oslc_disc:ServiceProvider>
<dc:title>Foo Bar Baz</dc:title>
<oslc_disc:details rdf:resource="foo"/>
<oslc_disc:services rdf:resource="bar"/>
<jfs_proc:consumerRegistry rdf:resource="baz"/>
</oslc_disc:ServiceProvider>
</oslc_disc:entry>
<oslc_disc:entry>
<oslc_disc:ServiceProvider dc:title="Foo Bar Baz II">
<oslc_disc:details rdf:resource="foo2"/>
<oslc_disc:services rdf:resource="bar2"/>
<jfs_proc:consumerRegistry rdf:resource="baz2"/>
</oslc_disc:ServiceProvider>
</oslc_disc:entry>
</oslc_disc:ServiceProviderCatalog>
这篇关于无法访问所有XML元素PERL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!