Saturday, January 15, 2011

xmllint for XML Namspace

With XML namespace, xmllint is not able to traverse it simply using the XML tags. There is not much examples on the Internet showing how xmllint handle XML with namespace and this blog serves to fill this gap. Let's try xmllint with this sample XML file
$ cat ns.xml
<?xml version="1.0"?>
<Tests xmlns="http://www.adatum.com">
  <Test TestId="0001" TestType="CMD">
    <Name>Convert number to string</Name>
    <CommandLine>Examp1.EXE</CommandLine>
    <Input>1</Input>
    <Output>One</Output>
  </Test>
  <Test TestId="0002" TestType="CMD">
    <Name>Find succeeding characters</Name>
    <CommandLine>Examp2.EXE</CommandLine>
    <Input>abc</Input>
    <Output>def</Output>
  </Test>
  <Test TestId="0003" TestType="GUI">
    <Name>Convert multiple numbers to strings</Name>
    <CommandLine>Examp2.EXE /Verbose</CommandLine>
    <Input>123</Input>
    <Output>One Two Three</Output>
  </Test>
  <Test TestId="0004" TestType="GUI">
    <Name>Find correlated key</Name>
    <CommandLine>Examp3.EXE</CommandLine>
    <Input>a1</Input>
    <Output>b1</Output>
  </Test>
  <Test TestId="0005" TestType="GUI">
    <Name>Count characters</Name>
    <CommandLine>FinalExamp.EXE</CommandLine>
    <Input>This is a test</Input>
    <Output>14</Output>
  </Test>
  <Test TestId="0006" TestType="GUI">
    <Name>Another Test</Name>
    <CommandLine>Examp2.EXE</CommandLine>
    <Input>Test Input</Input>
    <Output>10</Output>
  </Test>
</Tests>

$ xmllint --shell ns.xml
/ > cd Tests
Tests is a 0 Node Set
/ >

In order to traverse XML file with namespace defined, you need to set it with a prefix.

$ head -2 ns.xml
<?xml version="1.0"?>
<Tests xmlns="http://www.adatum.com">

$ xmllint --shell ns.xml
/ > setns a=http://www.adatum.com
/ > cd a:Tests
Tests > cd a:Test
a:Test is a 6 Node Set
Tests > cd a:Test[3]
Test > dir
ELEMENT Test
  ATTRIBUTE TestId
    TEXT
      content=0003
  ATTRIBUTE TestType
    TEXT
      content=GUI
Test > cat
<Test TestId="0003" TestType="GUI">
    <Name>Convert multiple numbers to strings</Name>
    <CommandLine>Examp2.EXE /Verbose</CommandLine>
    <Input>123</Input>
    <Output>One Two Three</Output>
  </Test>
Test >

If you have more than 1 namespace to work with, just set it with a different prefix name. You do not have to use the same namespace declaration mapping.

$ cat ns2.xml
<h:html xmlns:xdc="http://www.xml.com/books"
        xmlns:h="http://www.w3.org/HTML/1998/html4">
 <h:head><h:title>Book Review</h:title></h:head>
 <h:body>
  <xdc:bookreview>
   <xdc:title>XML: A Primer</xdc:title>
   <h:table>
    <h:tr align="center">
     <h:td>Author</h:td><h:td>Price</h:td>
     <h:td>Pages</h:td><h:td>Date</h:td></h:tr>
    <h:tr align="left">
     <h:td><xdc:author>Simon St. Laurent</xdc:author></h:td>
     <h:td><xdc:price>31.98</xdc:price></h:td>
     <h:td><xdc:pages>352</xdc:pages></h:td>
     <h:td><xdc:date>1998/01</xdc:date></h:td>
    </h:tr>
   </h:table>
  </xdc:bookreview>
 </h:body>
</h:html>


$ xmllint --shell ns2.xml
/ > cd h:html
h:html is a 0 Node Set
/ > setns h=http://www.w3.org/HTML/1998/html4
/ > setns xdc=http://www.xml.com/books
/ > cd h:html/h:body/xdc:bookreview/xdc:title
title > cat
<xdc:title>XML: A Primer</xdc:title>
title > 

Labels:

3 Comments:

Blogger Joshua Tolley said...

Thanks... exactly what I needed.

2:49 AM  
Blogger chihungchan said...

You are welcome

11:30 PM  
Blogger Lighton Phiri said...

Thank you for this, quite helpful. Spent a couple of minutes trying to figure out why I kept getting empty node results...

4:47 PM  

Post a Comment

<< Home