XML technologies
Namespaces with "xmlllint --xpath"
and with "xmlllint
--shell"
- The problem
- Use xmllint --shell
- Namespaces with xmllint --shell
-
We have been unsing the
xmllint --xpath
command as a
lightweight tool to experiment with XPath expressions.
This technique fails dismally when applied to XML files with namespaces!
For instance, to extract from our BookReview file the <xdc:title>
element, the only possible turnaround is
xmllint exnmsb.html --xpath "//*[local-name()='title' and
namespace-uri()='http://www.xml.com/books']"
which indeed yields
<xdc:title style="font-family: sans-serif;">XML: A
Primer</xdc:title>
Our command takes as arguments a filename and an XPath expression.
Since full URIs are much too cumbersome (see the example above), the only practical way to
write the expression will be to use prefixes.
But how can we declare the correspondence between those "local"
prefixes and
the namespace URIs of the XML file ?
In Java this is achieved through a NamespaceContext.
With xmllint --path
it is simply not possible !
-
The
--shell
option illustrates the analogy between an XML
tree and the tree of Unix directories.
See e.g. Playing With XPath Expressions in The xmllint Shell
to further illustrate the use of this command.
Examples (continued from XPath
course notes) :
jfp$ xmllint --shell Garage.xml
/
>
note the new "prompt" that tells us that we are at the
root
/ > xpath /Garage/Car/Engine/Ignition
without
quotes
Object is a Node Set :
Set contains 3 nodes:
1 ELEMENT Ignition
2 ELEMENT Ignition
3 ELEMENT Ignition
/ >
/ > xpath /Garage/Car/@make
Object is a Node Set :
Set contains 3 nodes:
1 ATTRIBUTE make
TEXT
content=Citro#C3#ABn
2 ATTRIBUTE make
TEXT
content=Renault
3 ATTRIBUTE make
TEXT
content=Toyota
/ >
/ > xpath count(/Garage/Car/Engine)
Object is a number : 3
/ >
... all the above examples may be played in this setting, e.g.
/ > xpath //Transmission[@gear_nb =
5]/../Body/@color
Object is a Node Set :
Set contains 2 nodes:
1 ATTRIBUTE color
TEXT
content=blue
2 ATTRIBUTE color
TEXT
content=white
/ >
Changing the evaluation context via cd
(analogy
node <-->
directory)
/ > cd Garage
Garage
>
note the change of prompt from '/
'
to 'Garage
'
Garage > xpath Car/Body[@color
= 'blue']
Object is a Node Set :
Set contains 1 nodes:
1 ELEMENT Body
ATTRIBUTE color
TEXT
content=blue
Garage >
Garage > cd Car
Car is a 3 Node Set cd
must
be deterministic !
Garage > cd Car/Body[@color = 'blue']
Body >
Body > xpath *
Object is a Node Set :
Set contains 1 nodes:
1 ELEMENT Hood
Body >
etc...exit via Ctrl-D
-
As opposed to the
--xpath
option, the --shell
option does provide a command to specify (prefix, URI) pairs :
setns prefix=URI
(one at a time)
Let us take up again our favorite example...
jfp$ xmllint --shell ../Namespaces/exnmsb.html
/ > setns bk=http://www.xml.com/books
/ >
/ > xpath //bk:title
Object is a Node Set :
Set contains 1 nodes:
1 ELEMENT xdc:title
ATTRIBUTE style
TEXT
content=font-family:
sans-serif;
/ >
/ > setns h=http://www.w3.org/1999/xhtml
empty
prefix not allowed
/ > xpath //h:title
Object is a Node Set :
Set contains 1 nodes:
1 ELEMENT title
/ > xpath //bk:title/text()
Object is a Node Set :
Set contains 1 nodes:
1 TEXT
content=XML: A Primer
/ > xpath //h:title/text()
Object is a Node Set :
Set contains 1 nodes:
1 TEXT
content=Book Review
/ >
That's the way things are...