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: XML
3 Comments:
Thanks... exactly what I needed.
You are welcome
Thank you for this, quite helpful. Spent a couple of minutes trying to figure out why I kept getting empty node results...
Post a Comment
<< Home