简体   繁体   中英

XML:Find particular node in XML using LibXML

I have an XML file which has only one node called import. I want to find the href attribute of import. I tried using findnodes(), but that returns a list I would have to search further, so I was hoping there was a way to find a particular node which has only one occurence. I tried getChildrenByTagName but that gives the error

Can't locate object method "getChildrenByTagName" via package "XML::LibXML::Document"

I also tried grep which gives a similar error

Can't locate object method "grep" via package "XML::LibXML::Document"

My XML file is:

<?xml version="1.0" encoding="UTF-8"?>
<resource name="data" type="application/dictionary+xml">
<schema>
    <import href="tobefound.xml"/>
</schema>
</resource>

My code so far is

#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML;

my $name = $ARGV[1];
my $dom = XML::LibXML->load_xml(location => $name);
my @node= $dom->findnodes('//import');
print "List: @node\n";

Please let me know if there is a way to find only one particular node without needing to traverse the whole dom and without having to store it as a list. Thank you.

XML doesn't guarantee uniqueness, so any sort of search will return a list of results. This list might be of length 0 or 1, just like with grep .

But the easy answer is to just grab the first result:

my ($node) = $dom -> findnodes('//import');

failing that - specify in your xpath:

my ( $node ) = $dom -> findnodes ( '(//import)[1]' ); 

I'm afraid I don't know if that latter will in fact bail out when 'enough' nodes have been selected though.

getChildrenByTagName is a method of Element nodes, not Document nodes.

my $doc = XML::LibXML->load_xml(location => $name);
my $root_ele = $doc->documentElement();
my ($import_ele) = $root_ele->getChildrenByTagName('import');

You could also use an XPath, though the equivalent XPath would be import (searches children), not //import (searches descendants).

my $doc = XML::LibXML->load_xml(location => $name);
my ($import_ele) = $doc->findnodes('import');

This returns all the import nodes and keeps the first. But can tell the search to stop looking after finding the first as follows:

my $doc = XML::LibXML->load_xml(location => $name);
my ($import_ele) = $doc->findnodes('import[1]');  # Short for 'import[position()=1]'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM