Reputation:
My basic requirement is to get element value from the XML file, i have used XMLDoxument.SelectSingleNode. My XML file contains some Namespace in header, so i have used NameSpaceManager to add namespace-prefix and i have used prefix to get that particular element. Now in my XML files that namespaces are getting vary, i don’t want to do any hard coding, is there any way that i can find out all the namespaces and i can add it to NameSpaceManager.
Thanks.
Upvotes: 16
Views: 22053
Reputation: 94
var xml = XDocument.Load(@"C:\Temp\file.xml");
var listnameSpaces = xml.Root.Attributes().Where(a => a.IsNamespaceDeclaration).ToList().ToDictionary(x => x.Name.LocalName, x => x.Name.Namespace);
Upvotes: 0
Reputation: 1669
Ruchita posted the working solution for XmlDocument
. But I wanted to do the same with XDocument
. Here is the very same with XDocument
:
var xml = XDocument.Load(filename);
var xmlNameSpaceList = ((IEnumerable)xml.XPathEvaluate(@"//namespace::*[not(. = ../../namespace::*)]")).Cast<XAttribute>();
var xmlNSmgr = new XmlNamespaceManager(new NameTable());
foreach (var nsNode in xmlNameSpaceList)
{
xmlNSmgr.AddNamespace(nsNode.Name.LocalName, nsNode.Value);
}
Now you can use XPath with namespaces, e.g. xml.XPathEvaluate("//test:p", xmlNSmgr)
.
Upvotes: 2
Reputation: 615
Namespaces can be found anywhere inside xml document. So to extract all namespaces and declare them into a XmlNamespaceManager I did the following:
public static XmlNamespaceManager getAllNamespaces(XmlDocument xDoc)
{
XmlNamespaceManager result = new XmlNamespaceManager(xDoc.NameTable);
IDictionary<string, string> localNamespaces = null;
XPathNavigator xNav = xDoc.CreateNavigator();
while (xNav.MoveToFollowing(XPathNodeType.Element))
{
localNamespaces = xNav.GetNamespacesInScope(XmlNamespaceScope.Local);
foreach (var localNamespace in localNamespaces)
{
string prefix = localNamespace.Key;
if (string.IsNullOrEmpty(prefix))
prefix = "DEFAULT";
result.AddNamespace(prefix, localNamespace.Value);
}
}
return result;
}
Just pay attention to the default namespace case. I redefined default namespace as "DEFAULT" prefix because I had problems when making SelectSingleNode using the above returned namespace manager when querying the default namespace. I was my workaround. Hope this helps
Upvotes: 17
Reputation: 3
If you're looking for a quick way to avoid the namespace issue, strip the namespace definitions out of the Xml via a RegEx before you do an XmlDocument.LoadXml(bla). I do this when parsing live XHTML pages. Takes the XmlDoc load time from 15 seconds to .15 seconds and makes it so that I don't have to prefix my xpaths.
Upvotes: -4
Reputation:
Thanks for your quick response...
I think the .Net version that you are using is must be latest one. I am using .Net framework 1.1 ... pretty old :( ..
By the time,, i have got some sample code like this.. for the same purpose...
XmlNodeList _xmlNameSpaceList = _xmlDocument.SelectNodes(@"//namespace::*[not(. = ../../namespace::*)]");
_xmlNSmgr = new XmlNamespaceManager(_xmlDocument.NameTable);
foreach(XmlNode nsNode in _xmlNameSpaceList)
{
_xmlNSmgr.AddNamespace(nsNode.LocalName,nsNode.Value);
}
Any comment will be appreciated to add knowledge to my KB... Thanks
Upvotes: 9
Reputation: 25775
Your basic problem of retrieving namespaces from an XmlDocument can be solved by simply retrieving the NameTable
of the XmlDocument and creating an XmlNameSpaceManager
from it.
However, if you want to list the namespaces for some other purpose, you should check out the GetNamespacesInScope
method exposed by the XmlNamespaceManager
class as well as the XPathNavigator
class.
When using an XmlDocument, you can get an XmlNamespaceManager from it via the following code:
//Instantiate an XmlDocument object.
XmlDocument xmldoc = new XmlDocument();
//Load XML file into the XmlDocument object.
xmldoc.Load("C:\\myFile.xml");
//Instantiate an XmlNamespaceManager object.
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmldoc.NameTable);
// Retrieve the namespaces into a Generic dictionary with string keys.
IDictionary<string, string> dic = nsMgr.GetNamespacesInScope(XmlNamespaceScope.All);
// Iterate through the dictionary.
...
In this article, Scott Hanselman presents a way to use this method to list all namespaces in a document using an XPathNavigator and using a LINQ bridge.
Upvotes: 3