现在的位置: 首页 > 综合 > 正文

.NET XmlNavigator with Namespace

2012年09月25日 ⁄ 综合 ⁄ 共 2138字 ⁄ 字号 评论关闭

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&>

抱歉!评论已关闭.