xmlperlurlxml-parsingxml-libxml

XML::LibXML issue finding XML nodes with a namespace


I am writing an XML parser and am having an issue with the program handling a link. I am attempting to parse an XML hierarchy Settings/Setting then findnode 'Value'. The following is an example of the XML:

<?xml version='1.0' ?>
<Settings xmlns='http://hme.com/Settings.xsd'>
  <Setting SID="0">
    <Name>Store ID</Name>
    <Value>72</Value>
  </Setting>
  <Setting SID="1">
    <Name>Deprecated</Name>
    <Value>0</Value>
  </Setting>
  <Setting SID="8">
    <Name>Open Store Hours Sunday</Name>
    <Value>25200</Value>
  </Setting>

Here is the code I am using to parse the XML

my $doc = $parser->parse_file($settings_file) or die "Couldn't parse timer settings\n";

#Sunday
for my $reviewer ($doc->findnodes('/Settings/Setting[@SID="8"]')) {
  my ($name) = $reviewer->findnodes('Value');
  $name->removeChildNodes();
  $name->appendText('109800');
}

When I remove the xmlns='http://hme.com/Settings.xsd' from the XML file, there is no issue with replacing the value node. Once I enter the link back in the XML, the code stops working and will not update the xml sheet. Is there a way to handle for this link or to remove it so I can properly update the file?


Solution

  • You ask to find nodes with namespace null and with name Settings. There are no such nodes in the document, so findnodes correctly returns nothing.

    You want to find the nodes with namespace http://hme.com/Settings.xsd and with name Settings. You can use the following to achieve that:

    my $xpc = XML::LibXML::XPathContext->new();
    $xpc->registerNs( s => 'http://hme.com/Settings.xsd' );
    
    for ($xpc->findnodes('/s:Settings/s:Setting[@SID="8"]'), $doc) {
       ...
    }