XPath and namespaces : a newbie question

O

Omar

Hi,
I would use your help parsing an XML file. I am new to XPath, and I
would like to use it parsing an XML file generated with dia, the file looks
like :
<?xml version="1.0" encoding="UTF-8"?>
<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
<dia:diagramdata>
<dia:attribute name="background">
<dia:color val="#ffffff"/>
</dia:attribute>
<dia:attribute name="pagebreak">
<dia:color val="#000099"/>
</dia:attribute>
</dia:diagramdata>
</dia:diagram>

I would need to match all the "attribute" nodes. I don't know wether the
XPath expression i'm using is wrong or whether the API (libxml2) i'm using
is loosy ...
Trying "//attribute" matches nothing, "//dia:attribute" gives the following
libxml error : "XPath error : Undefined namespace prefix" and the wierdest
thing is that :
"//*" matches all nodes with no errors... "/*" matches the "diagram" node
with no errors but ... "/diagram" matches nothing and neither does
"/dia:diagram" which actually gives the "XPath error : Undefined namespace
prefix". Can anyone help me !

Thanks in advance.
 
D

David Carlisle

Omar said:
Hi,
I would use your help parsing an XML file. I am new to XPath, and I
would like to use it parsing an XML file generated with dia, the file looks
like :
<?xml version="1.0" encoding="UTF-8"?>
<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
<dia:diagramdata>
<dia:attribute name="background">
<dia:color val="#ffffff"/>
</dia:attribute>
<dia:attribute name="pagebreak">
<dia:color val="#000099"/>
</dia:attribute>
</dia:diagramdata>
</dia:diagram>

I would need to match all the "attribute" nodes. I don't know wether the
XPath expression i'm using is wrong or whether the API (libxml2) i'm using
is loosy ...
Trying "//attribute" matches nothing,
It selects elements called attribute in no namespace, there are no such elements


"//dia:attribute" gives the following
libxml error : "XPath error : Undefined namespace prefix" and the wierdest
thing is that :
This is what you need, but you need to bind the prefix (which doesn;t
need to be teh same prefix as used in the source) to the namespace
http://www.lysator.liu.se/~alla/dia/
If the xpath is inside XSLT you bind a prefix using
xmlns:dia="http://www.lysator.liu.se/~alla/dia/"
but if calling an XPath API directly it will have alternative calls to
set up these bindings before evaluating the Xpath.

"//*" matches all nodes with no errors...

That selects all elements in any namespace

"/*" matches the "diagram" node

That selects the top level element bode.
with no errors but ... "/diagram" matches nothing

That selects the top level element if it is called diagram in no
namespace
and neither does
"/dia:diagram" which actually gives the "XPath error : Undefined namespace
prefix". Can anyone help me !

As above, this would work if you bind the dia prefix first.
Thanks in advance.

If it is inconvenient to bind namespace prefixes in your API then you
have the alternative of
//*[local-name()='attribute']
for example. Which selects all elements with local name 'attribute' in
any namespace.

David
 
P

Patrick TJ McPhee

[...]
% Trying "//attribute" matches nothing, "//dia:attribute" gives the following
% libxml error : "XPath error : Undefined namespace prefix" and the wierdest

If you're using libxml directly, use xmlXPathRegisterNs() to register
a namespace, something like

xmlXPathRegisterNs(xpc, "dia", "http://www.lysator.liu.se/~alla/dia/");

(where xpc is the xpath context pointer). The prefix (dia in this case)
doesn't have to be the same as the prefix used in your xml file, but
the URL has to match the name space definition in the xml file exactly.
 
O

Omar

Hi,
xmlXPathRegisterNs works quite fine. //*[local-name()='attribute'] :
works fine too, but I'm not quite convinced that this last one is convinient
from performance standpoint. I'm anyway a little surprised to see that the
parser does not automatically perform this binding. But I suppose this is an
API specific question, and out of scope of this newsgroup.

Thanks for your help.

Omar
 
P

Patrick TJ McPhee

% from performance standpoint. I'm anyway a little surprised to see that the
% parser does not automatically perform this binding. But I suppose this is an
% API specific question, and out of scope of this newsgroup.

You shouldn't be surprised. The name-space prefix is just a place-holder
for the name-space uri. The parser has no way of knowing what URI your
name-space prefix refers to unless you perform the binding. In a lot of
cases (e.g., any document with a default name space), the XPath expression
has to use a different name-space prefix than the one used in the
source document.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top