mrfangzheng

Hope and fear are useless. Be confident, and always be prepared for the worst.
  首页  :: 新随笔  :: 联系 :: 管理

.NET XmlNavigator with Namespace

Posted on 2008-04-07 16:13  mrfangzheng  阅读(278)  评论(0编辑  收藏  举报

In .NET 2.0 there is additional overload that accepts string expression
and IXmlNamespaceResolver (XmlNamespaceManager implements it) - see
http://msdn2.microsoft.com/en-us/library/6k4x060d.aspx.

XPathDocument document = new XPathDocument("contosoBooks.xml");
XPathNavigator navigator 
= document.CreateNavigator();

XmlNamespaceManager manager 
= new XmlNamespaceManager(navigator.NameTable);
manager.AddNamespace(
"bk""http://www.contoso.com/books");

XPathNodeIterator nodes 
= navigator.Select("/bk:bookstore/bk:book", manager);
XPathNavigator nodesNavigator 
= nodes.Current;

XPathNodeIterator nodesText 
= nodesNavigator.SelectDescendants(XPathNodeType.Text, false);

while (nodesText.MoveNext())
{
    Console.Write(nodesText.Current.Name);
    Console.WriteLine(nodesText.Current.Value);
}


In .NET 1.1 you have no choice but to compile XPathExpression manually:

XPathExpression expr = nav.Compile("book/@bk:ISBN");
XmlNamespaceManager mngr = new XmlNamespaceManager(new NameTable());
mngr.AddNamespace("bk","urn:samples");
expr.SetContext(mngr);
XPathNodeIterator ni = nav.Select(expr);

See
http://msdn.microsoft.com/library/d...ecttopic2 .asp

--------------------------------------------------------------------------------


Thanks Oleg, it works a treat (but what a polaver though).

One small follow-up if I may. I would have thought that if I initialized the
namespace manager like this:

XmlNamespaceManager mngr = new XmlNamespaceManager(nav.NameTable);

then it would pick up the namespace prefixes from the document. However, it
doesn't (I still need to do the AddNamespace calls)

 --------------------------------------------------------------------------------

No, first of all NameTable has nothing to do with namespaces - it's just
a collection of atomic strings (names) used to save memory and speed
up name comparisons. Second - there is no such thing as "prefixes from
the document" as in XML document namespace prefixes can be overriden and
undeclared in any order.

The NameTable is used to speed up string comparison, there is nothing
done like "picking up namespace prefixes".
As said, with .NET 2.0 you have some way to use the XPathNavigator
itself, once moved to the proper node you want to "pick up namespace
prefixes" from, itself as the namespace manager.
<http://groups.google.com/group/microsoft.public.dotnet.xml/msg/af7d7f9e2f422d7e?hl=en&>