Reputation: 333
Given the XML snippet bellow how do I tell the difference between
<entry xmlns:georss="...">
with the children
<title>fileName1.jpg</title>
and
<entry><title type="text">fileName.pdf</title></entry>
I'm using XML::LibXML
to loop through the <entry>
but this gets each one so the connection between <type>
and <link>
is lost. I need to test at the <entry>
level not the child <type>
level
Can you test if entry node has georss namespace?
Something like this gets the value of <type>
foreach my $Entry ($dom->findnodes("//dft:feed/dft:entry")) {
foreach my $Images ($dom->findnodes("//dft:title[not(\@type='text')]", $Entry)) {
my $ImageVal = $Images->textContent;
#### This finds all the Images
}
}
XML Snippet
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:georss="http://www.georss.org/georss">
<entry xmlns:georss="http://www.georss.org/georss/10" xsi:schemaLocation ="http://www.url1.net/path/ http://www.url2.net/path/11 http://www.url3.net/path/23" >
<title>fileName1.jpg</title>
<link href="PathTo/fileName1.jpg" />
</entry>
<entry xmlns:georss="http://www.georss.org/georss/10" xsi:schemaLocation ="http://www.url1.net/path/ http://www.url2.net/path/11 http://www.url3.net/path/23" >
<title>fileName2.jpg</title>
<link href="PathTo/fileName2.jpg" />
</entry>
<entry>
<title type="text">fileName.pdf</title>
<link type="application/pdf" href="PathTo/fileName.pdf" />
</entry>
</feed>
Upvotes: 0
Views: 190
Reputation: 126722
Can you test if entry node has
georss
namespace?
There is no data in your example that is in the georss
namespace. Everything is in the namespace http://www.w3.org/2005/Atom
defined in the feed
element. The definition xmlns:georss="http://www.georss.org/georss/10"
just specifies a namespace prefix georss
, but that prefix is never used
You need to create an XML::LibXML::XPathContext
object attached to the XML::LibXML
document that allows you to specify namespace abbreviations. The code looks like below
Note that I've also had to fix your XML data to include a definition of the xsi
namespace, as without it the data is not well-formed
You shouldn't make a habit of adding //
at the start of every XPath expression. It forces the XPath engine to unnecessarily search the entire document each time, and an explicit XPath from the root is better practice. It also produces the wrong result with your XPath //dft:title[not(@type='text')]
because you're starting the search from the root each time and ignoring the entry
context node. Just dft:title[not(@type="text")]
is correct
use strict;
use warnings 'all';
use XML::LibXML;
use XML::LibXML::XPathContext;
my $dom = XML::LibXML->load_xml( location => 'feed.xml' );
my $xpc = XML::LibXML::XPathContext->new($dom);
$xpc->registerNs( dft => 'http://www.w3.org/2005/Atom' );
$xpc->registerNs( georss => 'http://www.georss.org/georss/10' );
for my $entry ($xpc->findnodes('/dft:feed/dft:entry')) {
for my $images ($xpc->findnodes('dft:title[not(@type="text")]', $entry)) {
my $image_val = $images->textContent;
print $image_val, "\n";
}
}
fileName1.jpg
fileName2.jpg
Upvotes: 1