Hello Yair,
We had this same question a couple of weeks ago. I couldn't answer it then
but I investigated and a guy** in the dotnet.xml newsgroup helped an awful
lot. Now that I know, I'll try and put you right too.
Do you know about namespaces in xml - whereby you can have
<yair:foobar>...</yair:foobar> and <fergus:foobar>...</fergus:foobar> - the
'yair' and 'fergus' being the namespace prefixes ?
<example>
<yair:foobar>...</yair:foobar>
<fergus:foobar>...</fergus:foobar>
</example>
To do a search for <your> foobars the XPath would have to be
"//yair:foobar". A search for "//foobar" will return nothing because there are
no foobars without a namespace prefix.
That's pretty straightforward.
Now, when you introduce a schema using xmlns="
http://tempuri.org/obj.xsd"
or some such, what you are doing is saying that <all> elements under the one
introducing the namespace, that don't have an explicit namespace prefix, will
have a default namespace (which is implicit and has an 'unnamed prefix').
Consider:
<example>
<foobar> (1) No namespace </foobar>
<lets_have_a_namespace
xmlns="FooBarTheElephant-Sep26th-1am">
<yair:foobar> (2) Yair namespace </yair:foobar>
<fergus:foobar> (3) Fergus namespace </fergus:foobar>
<foobar> (4) Default namespace </foobar>
</lets_have_a_namespace >
</example>
(1) This foobar has no namespace because it hasn't been given one and
there is no default in place.
(2), (3) These foobars have explicit namespaces. Can't miss 'em.
(4) This foobar has a default namespace which you can't see. It was
introduced in the enclosing element but it has no prefix. However, to find it
using XPath*, you <must provide> its prefix. Which is impossible!!!
The solution is to give it a prefix - not in the xml itself, as the whole
point of default namespaces is to save you having to add the namespace prefix
to every tag which doesn't have one - but in the code which does the
SelectNodes.
What you have to do is introduce a NamespaceManager.
oXmlDoc.Load ("C:\Foo\Bar.xml")
Dim oNamespaceMgr As XmlNamespaceManager _
= new XmlNamespaceManager (oXmlDoc.NameTable)
oNamespaceMgr.AddNamespace ("wow", "
http://tempuri.org/obj.xsd")
Root = oXmlDoc.DocumentElement
NodeList = Root.SelectNodes ("//wow:foobar", oNamespaceMgr);
This time, using the example above, NodeList will contain (4) - the
unprefixed (default namespace) foobar.
The prefix 'wow' is totally arbitrary - you can give the NamespaceManager
any prefix you like - just so long as it doesn't clash with any other prefix
in the document and, of course, that you use it in your XPath.
The namespace given to the NamespaceManager must match the one in the
document <exactly> (ie. use cut and paste).
=======================================
About namespaces (for your info).
You are using the namespace "
http://tempuri.org/obj.xsd". The thing about
namespaces is not that they mean anything but that they are arbitrary and
unique - practically anything is allowed. The reason that URLs are so often
given is that URLs are unique - if chosen well. If everyone uses the tempuri
URL, as you have, there could be clashes of namespaces when two xml documents
are merged. The advice is to use, or make up, a URL that would aply to you or
your company <only>. So
http://Yair.com/my-unique-namespace/Sep26th-12-20am
would be pretty well unique. It doesn't even have to exist as a web site - it
is just an identifying string.
=======================================
Further reading:
This site has an excellent yet simple XML Namespaces FAQ.
http://www.rpbourret.com/xml/NamespacesFAQ.htm
There's also "XML Namespaces and How They Affect XPath and XSLT" by Dare
Obasanjo which is heavier reading. (I didn't finish it, lol, but I read it
before the other one)
http://msdn.microsoft.com/library/en-us/dnexxml/html/xml05202002.asp
Regards,
Fergus
=======================================
*XPath 1.0 has this default-namespace-requires-a-prefix-after-all issue. It
will be fixed in XPath 2.0
** Thanks to Oleg Tkachenko of dotnet.xml for teaching me a lot.
[2nd posting - 1st was deleted :-(]