I'm assuming that you're using
XML::LibXML
?
It's very important to explain what tools (library, language, operating system) you are using, as well as the errant behaviour you are seeing.
Your "Please note that the variable $fileLocation
here opens the file location for the XML I am working with" is troubling. It doesn't make much sense (it's a variable and cannot open anything) and the identifier you have chosen implies that it is a path to the XML file.
But to be able to call findnodes
on it, it must be a DOM object, more specifically an instance of XML::LibXML::Node
or a subclass.
Your code should look more like this
use XML::LibXML;
my $xml_file = '/path/to/file.xml';
my $dom = XML::LibXML->load_xml(
location => $xml_file
);
my @sections = $dom->findnodes('//section');
for my $section ( @sections ) {
next unless $section->hasAttribute('name');
say $section->getAttribute('name');
}
The result of the findnodes
method in scalar context is not a single
XML::LibXML::Node
object, but instead an
XML::LibXML::NodeList
,
which is overloaded so that it bahaves similarly to a reference to an array
You don't say what errors you are getting, but from your "Can someone please explain what is wrong with this syntax?" I imagine that the module is rejecting your XPath expression?
In this statement
my $some_att = $fileLocation->findnodes("//section[/@name]")
the problem is with the predicate [/@name]
which, if it were correct, would filter the section
elements to include only those that have a name
attribute. Because it is a predicate it doesn't need a child axis, and so should be written as //section[@name]
But that will only find all section
elements that have a name
attribute. To select the attributes themselves you need to write //section/@name
, something like this
my $section_names = $fileLocation->findnodes('//section/@name')
Then you will have an XML::LibXML::NodeList
of
XML::LibXML::Attr
objects, and you can extract the list of their values using something similar to
my @section_names = map { $_->value } $section_names->get_nodelist
You may instead prefer to start with a list of all section
elements using the XPath expression //section
. That would give you a collection of
XML::LibXML::Element
objects, from which you can extract the name
element using $elem->getAttribute('name')
Remember that you may work with arrays instead of
XML::LibXML::NodeList
objects if you prefer, by choosing list context instead of scalar context in the call to findnodes
as described in
mob's answer