By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,383 Members | 2,070 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,383 IT Pros & Developers. It's quick & easy.

Xpath with namespaces

P: n/a
Hello Everyone,

I am having an issue with xml and namespaces, at least I think it is
namespaces. When I use namespaces, I cannot use SelectSingleNode /
SelectNodes as they always return 0/Nothing respectively. Anyone have any
thoughts?

Thanks in advance

VB.Net 2005
WinXP Sp2

Test code:

Dim objXML As System.Xml.XmlDocument

'Test XML 1 ==Always returns 0
objXML = New System.Xml.XmlDocument
objXML.Load(Application.StartupPath & "\xmlfile1.xml")
MsgBox(objXML.SelectNodes("top/middle").Count)

'Test XML 2 ==Always returns expected results
objXML = New System.Xml.XmlDocument
objXML.Load(Application.StartupPath & "\xmlfile2.xml")
MsgBox(objXML.SelectNodes("top/middle").Count)

XML File 1
<?xml version="1.0" encoding="utf-8" ?>
<top xmlns="urn:bob" xmlns:firstns="urn:firstns"
xmlns:secondns="urn:secondns">
<middle firstns:name="Entry1" secondns:value="Value1">Some Data
Here</middle>
</top>
XML File 2
<?xml version="1.0" encoding="utf-8" ?>
<top>
<middle name="Entry1" value="Value1">Some Data Here</middle>
</top>
Oct 11 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
* AMDRIT wrote in microsoft.public.dotnet.xml:
>I am having an issue with xml and namespaces, at least I think it is
namespaces. When I use namespaces, I cannot use SelectSingleNode /
SelectNodes as they always return 0/Nothing respectively. Anyone have any
thoughts?
You have to declare your namespaces first using e.g. a custom
XmlNamespaceManager or you have to rewrite your expressions to
avoid them like

//foo:bar -//*[local-name() = 'bar' namespace-uri() = '...']
--
Björn Höhrmann · mailto:bj****@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Oct 11 '06 #2

P: n/a
I appreciate your response, however it is leading me nowhere. I have
discovered XMLNamespaceManager prior to posting, the docs are not clear how
this resolved my issue.

First, I am not attempting to get to the attributes yet, merely attempting
to count the number of 'middle' nodes in 'top'. So I do not see how I would
change my xpath statement to reflect namespaces.

Second, when I create a document from scratch using these namespaces and
attempt to xpath through the document I am not having any issues. Any ideas
why?

Sample Code to Count Nodes (XML Loaded from File)

Dim objXML As System.Xml.XmlDocument
Dim objNSMGR As Xml.XmlNamespaceManager

objXML = New System.Xml.XmlDocument
objXML.Load(Application.StartupPath & "\xmlfile1.xml")

objNSMGR = New System.Xml.XmlNamespaceManager(objXML.NameTable)

objNSMGR.AddNamespace("firstns", "urn:firstns")
objNSMGR.AddNamespace("secondns", "urn:secondns")

MsgBox(objXML.SelectNodes("top/middle", objNSMGR).Count)

Sample Code to create an query XML

Dim objXML As System.Xml.XmlDocument
Dim objNode As System.Xml.XmlNode
objXML = New System.Xml.XmlDocument

'Create root node
objNode = objXML.CreateNode(Xml.XmlNodeType.Element, "top", "")

'create namespaces
objNode.Attributes.Append(objXML.CreateAttribute(" xmlns"))
objNode.Attributes.GetNamedItem("xmlns").Value = "urn:bob"

objNode.Attributes.Append(objXML.CreateAttribute(" xmlns:firstns"))
objNode.Attributes.GetNamedItem("xmlns:firstns").V alue = "urn:firstns"

objNode.Attributes.Append(objXML.CreateAttribute(" xmlns:secondns"))
objNode.Attributes.GetNamedItem("xmlns:secondns"). Value = "urn:secondns"

'Append root node to #document
objXML.AppendChild(objNode)

'Create first child node
objNode = objXML.CreateNode(Xml.XmlNodeType.Element, "middle", "")

'Create first attribute with namespace-uri
objNode.Attributes.Append(objXML.CreateAttribute(" firstns:name",
"urn:firstns"))
objNode.Attributes.GetNamedItem("firstns:name").Va lue = "test"

'Append node to root node
objXML.SelectSingleNode("top").AppendChild(objNode )

'Count all occurances of middle in top
MsgBox(objXML.SelectNodes("top/middle").Count)
"Bjoern Hoehrmann" <bj****@hoehrmann.dewrote in message
news:la********************************@hive.bjoer n.hoehrmann.de...
>* AMDRIT wrote in microsoft.public.dotnet.xml:
>>I am having an issue with xml and namespaces, at least I think it is
namespaces. When I use namespaces, I cannot use SelectSingleNode /
SelectNodes as they always return 0/Nothing respectively. Anyone have any
thoughts?

You have to declare your namespaces first using e.g. a custom
XmlNamespaceManager or you have to rewrite your expressions to
avoid them like

//foo:bar -//*[local-name() = 'bar' namespace-uri() = '...']
--
Björn Höhrmann · mailto:bj****@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/

Oct 11 '06 #3

P: n/a
* AMDRIT wrote in microsoft.public.dotnet.xml:
>I appreciate your response, however it is leading me nowhere. I have
discovered XMLNamespaceManager prior to posting, the docs are not clear how
this resolved my issue.
Any and all elements and attributes in an XML document have a name-
space name and a local name associated with it, in your example

<?xml version="1.0" encoding="utf-8" ?>
<top xmlns="urn:bob" xmlns:firstns="urn:firstns"
xmlns:secondns="urn:secondns">
<middle firstns:name="Entry1" secondns:value="Value1">Some Data
Here</middle>
</top>

you have

<{urn:bob}top>
<{urn:bob}middle {urn:firstns}name="Entry1"
{urn:secondns}value="Value1">Some Data here
...

Your XPath expression "top/middle" ignores elements in the 'urn:bob'
namespace, it matches middle elements in no namespace that have a parent
top element in no namespace. In your example, the elements are in a
namespace however. You have to specify this namespace in the XPath, like

"foo:top/foo:middle"

and the prefix "foo" needs to be bound to "urn:bob"; XmlNamespace-
Manager does just that.
--
Björn Höhrmann · mailto:bj****@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Oct 12 '06 #4

P: n/a


AMDRIT wrote:

Dim objXML As System.Xml.XmlDocument
Dim objNSMGR As Xml.XmlNamespaceManager

objXML = New System.Xml.XmlDocument
objXML.Load(Application.StartupPath & "\xmlfile1.xml")

objNSMGR = New System.Xml.XmlNamespaceManager(objXML.NameTable)

objNSMGR.AddNamespace("firstns", "urn:firstns")
objNSMGR.AddNamespace("secondns", "urn:secondns")

MsgBox(objXML.SelectNodes("top/middle", objNSMGR).Count)
You have to use the prefixes in your XPath expressions to qualify
element or attributes and you need a prefix for the default namespace
the XML has e.g.
objNSMGR.AddNamespace("bb", "urn:bob")

objXML.SelectNodes("bb:top/bb:middle", objMSNGR).Count

See <http://www.faqts.com/knowledge_base/view.phtml/aid/34022/fid/616>
for some more explanation.
--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Oct 12 '06 #5

P: n/a


AMDRIT wrote:

Second, when I create a document from scratch using these namespaces and
attempt to xpath through the document I am not having any issues.
Dim objXML As System.Xml.XmlDocument
Dim objNode As System.Xml.XmlNode
objXML = New System.Xml.XmlDocument

'Create root node
objNode = objXML.CreateNode(Xml.XmlNodeType.Element, "top", "")
Yes, you have issues, your are _not_ creating the element in any
namespace. With the DOM the namespace an element or attribute belongs to
is determined when it is created so your code creates an element named
"top" in no namespace.

If you serialized your XML then you would see that the top element is in
no namespace. If you want to use the DOM to create an element in a
certain namespace then you can do e.g.

XmlElement topElement = objXML.CreateElement("top", "urn:bob")

that is you use a method that takes a namespace URI and you pass in the
namespace URI of the namespace you want the element to belong to.

--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Oct 12 '06 #6

P: n/a
Thank you for the clear response. I am off and running again.

"Martin Honnen" wrote:
>

AMDRIT wrote:

Dim objXML As System.Xml.XmlDocument
Dim objNSMGR As Xml.XmlNamespaceManager

objXML = New System.Xml.XmlDocument
objXML.Load(Application.StartupPath & "\xmlfile1.xml")

objNSMGR = New System.Xml.XmlNamespaceManager(objXML.NameTable)

objNSMGR.AddNamespace("firstns", "urn:firstns")
objNSMGR.AddNamespace("secondns", "urn:secondns")

MsgBox(objXML.SelectNodes("top/middle", objNSMGR).Count)

You have to use the prefixes in your XPath expressions to qualify
element or attributes and you need a prefix for the default namespace
the XML has e.g.
objNSMGR.AddNamespace("bb", "urn:bob")

objXML.SelectNodes("bb:top/bb:middle", objMSNGR).Count

See <http://www.faqts.com/knowledge_base/view.phtml/aid/34022/fid/616>
for some more explanation.
--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Oct 12 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.