Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading XML with default namespace

Tags:

xml

xpath

axapta

Consider this job which work:

static void XMLTest(Args _args)
{
    str xml = @'<?xml version="1.0" encoding="UTF-8"?>
       <tests xmlns="abc">
           <test>
               <testnumber><id>1</id></testnumber>
               <testname>bla bla</testname>
           </test>
       </tests>
   ';
   XMlDocument doc = XMLDocument::newXML(xml);
   XMLNodeList tests = doc.selectNodes('//tests/test');
   XMLNode node;
   for (node = tests.nextNode(); node; node = tests.nextNode())
   {
       info(node.selectSingleNode('testnumber/id').text());
       info(node.selectSingleNode('testname').text());
   }
}

It outputs "1" and "bla bla" as expected.

Now change the second line of the xml from:

<tests>

to:

<tests xmlns="xyz">

Now it fails to read anything.

How to read XML with a default namespace?

like image 931
Jan B. Kjeldsen Avatar asked Feb 14 '26 13:02

Jan B. Kjeldsen


1 Answers

You could do it the strict way via an instance of XMLNamespaceManager like so

static void XMLTest(Args _args)
{
    str xml = @'<?xml version="1.0" encoding="UTF-8"?>
       <tests xmlns="abc">
           <test>
               <testnumber><id>1</id></testnumber>
               <testname>bla bla</testname>
           </test>
       </tests>
   ';
   XMlDocument doc = XMLDocument::newXML(xml);
   XMLNamespaceManager nsMgr = new XMLNamespaceManager(new XmlNameTable());
   XMLNodeList tests;
   XMLNode node;
   ;

   nsMgr.addNamespace('x', 'abc');
   tests = doc.selectNodes("//x:tests/x:test", nsMgr);

   for (node = tests.nextNode(); node; node = tests.nextNode())
   {
       info(node.selectSingleNode('x:testnumber/x:id', nsMgr).text());
       info(node.selectSingleNode('x:testname', nsMgr).text());
   }
}

If for sure no naming conflicts will occur, you may want to ignore the namespace and match the nodes via local-name() like so

static void XMLTest2(Args _args)
{
    str xml = @'<?xml version="1.0" encoding="UTF-8"?>
       <tests xmlns="abc">
           <test>
               <testnumber><id>1</id></testnumber>
               <testname>bla bla</testname>
           </test>
       </tests>
   ';
   XMlDocument doc = XMLDocument::newXML(xml);
   XMLNodeList tests = doc.selectNodes("//*[local-name()='tests']/*[local-name()='test']");
   XMLNode node;
   for (node = tests.nextNode(); node; node = tests.nextNode())
   {
       info(node.selectSingleNode("*[local-name()='testnumber']/*[local-name()='id']").text());
       info(node.selectSingleNode("*[local-name()='testname']").text());
   }
}
like image 119
DAXaholic Avatar answered Feb 16 '26 07:02

DAXaholic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!