Groups | Blog | Home
all groups > dotnet xml > october 2003 >

dotnet xml : XPath and namespace problem


Andreas Håkansson
10/3/2003 8:24:39 PM
I have a price of XML that looks like this

<Root>
<SomeNode>
.....
</SomeNode>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
...
</Signature>
</Root>

If I load this into an XmlDocument object and try calling
SelectSingleNode("//Signature") to
determine if the signature has been added or not, then it alwasy return
null. I have managed
to get it that I probably need a XmlNamespaceManager object and pass it to
the method
as well, however I do not know how to set this up since the new namespace
declared in
the <Signature> node doesn't use a prefix and I can not alter the XML to
setup a prefix
either since the <Signature> section is generated by some other code and
need to comply
with a W3C schema =)

Any suggestions on how to be able to tell if the <Signature> node it present
or not, using
XPath and a XmlNamespaceManager object ? =)

--
ANDREAS HÅKANSSON
STUDENT OF SOFTWARE ENGINEERING
andreas (at) selfinflicted.org

Andreas_Håkansson
10/3/2003 9:07:53 PM
Nevermind.. figured it out..=20

Create a fake namespace alias in the XmlNamespaceManager and prefix you =
node in the
XPath with it..

XmlNamespaceManager manager =3D new XmlNamespaceManager();
manager.AddNamespace("test", "http://www.w3.org/2000/09/xmldsig#");

XmlNode n =3D doc.SelectSingleNode("//test:Signature");

=3D)


--=20
ANDREAS H=C5KANSSON
STUDENT OF SOFTWARE ENGINEERING
andreas (at) selfinflicted.org
[quoted text, click to view]
I have a price of XML that looks like this

<Root>
<SomeNode>
.....
</SomeNode>
<Signature xmlns=3D"http://www.w3.org/2000/09/xmldsig#">
...
</Signature>
</Root>

If I load this into an XmlDocument object and try calling
SelectSingleNode("//Signature") to
determine if the signature has been added or not, then it alwasy =
return
null. I have managed
to get it that I probably need a XmlNamespaceManager object and pass =
it to
the method
as well, however I do not know how to set this up since the new =
namespace
declared in
the <Signature> node doesn't use a prefix and I can not alter the XML =
to
setup a prefix
either since the <Signature> section is generated by some other code =
and
need to comply
with a W3C schema =3D)

Any suggestions on how to be able to tell if the <Signature> node it =
present
or not, using
XPath and a XmlNamespaceManager object ? =3D)

--=20
ANDREAS H=C5KANSSON
STUDENT OF SOFTWARE ENGINEERING
Dimitre Novatchev
10/3/2003 9:34:52 PM
You do not need to alter the source.xml in order to be able to use a
prefix -- what counts is the namespace-uri and not the prefix.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL



[quoted text, click to view]

Wray Smallwood
10/9/2003 1:12:50 AM
Thanks, I was looking for a workaround as well as I could not get mine =
to work. However despite the fact that what you have come up with below =
works, in my opinion this is a blatant bug.

To be specific if you have a DefaultNamespace you have to fudge an XPath =
search to make it work:

If your XML "xmlfile1.xml" has:

<?xml version=3D"1.0" encoding=3D"utf-8" ?><myObject =
xmlns=3D"http://tempuri.org/MyObject.xsd"><Object1> ...etc

which has a default namespace, instead of one with a named namespace =3D =
"anamespace":

<?xml version=3D"1.0" encoding=3D"utf-8" ?><myObject =
xmlns:anamespace=3D"http://tempuri.org/MyObject.xsd"><Object1> ...etc

then the following code will not work!!!!

Dim xdd As XmlDocument =3D New XmlDocument
xdd.Load("..\xmlfile1.xml")
Dim nod As XmlNode
Dim nsmgr As XmlNamespaceManager =3D New =
XmlNamespaceManager(xdd.NameTable)
nsmgr.AddNamespace(String.Empty, "http://tempuri.org/MyObject.xsd") ' =
Add a default namespace
nod =3D xdd.SelectSingleNode("//Object1", nsmgr)

The node is not found despite the fact that the documentation for .NET =
says that it will.

Fudging the last two lines works:
nsmgr.AddNamespace("fakenamespace", "http://tempuri.org/MyObject.xsd") =
' Add a default namespace
nod =3D xdd.SelectSingleNode("//fakenamespace:Object1", nsmgr)

This bug is probably very closely related to 324996=20

BUG: XmlNamespaceManager Does Not Correctly Atomize Strings During =
Namespace Lookups

However it isn't quite the same bug and if they fix 324996 they may not =
fix this one. If anyone that has MSDN Universal or some other means of =
logging a bug with Microsoft wants to be the first to log a new one, go =
ahead. I neither know how, nor have any premium support from Microsoft.=20

Note that one of the reasons this may not be a trivial bug is that =
Visual Studio itself uses default namespaces. An XSD file that is used =
for a dataset leads to an XML data file with a default namespace. So =
XPath's searches don't work on XMLDataDocuments.


Wray Smallwood







[quoted text, click to view]
Nevermind.. figured it out..=20

Create a fake namespace alias in the XmlNamespaceManager and prefix you =
node in the
XPath with it..

XmlNamespaceManager manager =3D new XmlNamespaceManager();
manager.AddNamespace("test", "http://www.w3.org/2000/09/xmldsig#");

XmlNode n =3D doc.SelectSingleNode("//test:Signature");

=3D)


--=20
ANDREAS H=C5KANSSON
STUDENT OF SOFTWARE ENGINEERING
andreas (at) selfinflicted.org
[quoted text, click to view]
I have a price of XML that looks like this

<Root>
<SomeNode>
.....
</SomeNode>
<Signature xmlns=3D"http://www.w3.org/2000/09/xmldsig#">
...
</Signature>
</Root>

If I load this into an XmlDocument object and try calling
SelectSingleNode("//Signature") to
determine if the signature has been added or not, then it alwasy return
null. I have managed
to get it that I probably need a XmlNamespaceManager object and pass it =
to
the method
as well, however I do not know how to set this up since the new =
namespace
declared in
the <Signature> node doesn't use a prefix and I can not alter the XML to
setup a prefix
either since the <Signature> section is generated by some other code and
need to comply
with a W3C schema =3D)

Any suggestions on how to be able to tell if the <Signature> node it =
present
or not, using
XPath and a XmlNamespaceManager object ? =3D)

--=20
ANDREAS H=C5KANSSON
STUDENT OF SOFTWARE ENGINEERING
Oleg Tkachenko
10/9/2003 10:49:28 AM
[quoted text, click to view]
Not really, that's the fact of the reality :) That's how XPath 1.0 was
designed - it doesn't support default namespace. Any non-prefixed name in
XPath data model is treated as name in no namespace. Full stop.

[quoted text, click to view]
"To fudge"? :) No, but one has to consider abovementioned fact and read more
about XPath. "Object1" in XPath means Object1 element in *null namespace*. See
http://www.w3.org/TR/xpath#node-tests
"This is the same way expansion is done for element type names in start and
end-tags except that the default namespace declared with xmlns is not used: if
the QName does not have a prefix, then the namespace URI is null (this is the
same way attribute names are expanded)."

[quoted text, click to view]
I don't believe it does. Moreover, XmlNode.SelectSingleNode Method (String)
documentation in MSDN says:
"Note If the XPath expression does not include a prefix, it is assumed that
the namespace URI is the empty namespace. If your XML includes a default
namespace, you must still use the XmlNamespaceManager and add a prefix and
namespace URI to it; otherwise, you will not get a selected node."
--
Oleg Tkachenko
http://www.tkachenko.com/blog
Multiconn Technologies, Israel
AddThis Social Bookmark Button