how i can list out all the namespace in XML?
Asked Answered
L

6

16

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.

Laurent answered 20/4, 2009 at 9:26 Comment(1)
@Ruchita: The problem with this approach is that namespaces declarations can be overwrote (in XML 1.0 default namespace declaration can be also reseted, in XML 1.1 all namespace declarations)Lovel
U
17

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

Unidirectional answered 6/11, 2014 at 17:51 Comment(1)
Great answer. Thank you.Springspringboard
L
9

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

Laurent answered 20/4, 2009 at 12:4 Comment(2)
good old XPath, works perfectly well, it retrieves all nodes with namespaces. thanksNolita
Get the exception prefix xmlns is reserved for use by xml in the foreach loop, anyone know why?Smite
B
3

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.

Blinny answered 20/4, 2009 at 9:45 Comment(3)
This doesn't seem to work for me. There are lots of items in the document's NameTable, but several namespaces defined in the beginning of the document are not being added to the XmlNamespaceManager. I keep getting "Namespace not defined" in my SelectNodes calls, unless I add the namespaces manually to the manager. I need a solution that accurately reads the namespaces defined in the XML document, and adds them to my namespace manager so I don't have to hard code them.Cyclist
@SeanWorle It's a bit late, but check out Get namespaces from an XML Document with XPathDocument and LINQ to XML, perhaps it could help you or someone else.Hallucinatory
The problem with this approach is it ignores the "xmlns" entries.Dullard
C
2

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).

Confirm answered 7/2, 2018 at 15:39 Comment(0)
G
0
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);
Gloat answered 27/9, 2021 at 13:29 Comment(0)
C
-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.

Chukker answered 6/4, 2011 at 18:34 Comment(1)
bro, you can't do that, two elements can be named the same, but from different namespaces e.g. <persons:id> and <cars:id>Novelette

© 2022 - 2024 — McMap. All rights reserved.