我如何列出XML中的所有命名空间?

时间:2009-04-20 09:26:07

标签: c# .net xml namespaces

我的基本要求是从XML文件中获取元素值,我使用了XMLDoxument.SelectSingleNode。我的XML文件在头文件中包含一些Namespace,所以我使用了NameSpaceManager来添加namespace-prefix,并且我使用了prefix来获取该特定元素。现在在我的XML文件中,命名空间变得越来越多,我不想做任何硬编码,有什么方法可以找到所有命名空间,我可以将它添加到NameSpaceManager。

感谢。

5 个答案:

答案 0 :(得分:14)

可以在xml文档中的任何位置找到命名空间。因此,要提取所有名称空间并将它们声明为XmlNamespaceManager,我执行了以下操作:

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;
}

注意默认的命名空间情况。我将默认命名空间重新定义为“DEFAULT”前缀,因为在查询默认命名空间时使用上面返回的命名空间管理器制作SelectSingleNode时遇到问题。我是我的解决方法。 希望这有帮助

答案 1 :(得分:8)

感谢您的快速回复...

我认为您使用的.Net版本必须是最新版本。我正在使用.Net framework 1.1 ...很老:( ..

到时候,我有一些这样的示例代码...出于同样的目的...

XmlNodeList _xmlNameSpaceList =  _xmlDocument.SelectNodes(@"//namespace::*[not(. = ../../namespace::*)]");

            _xmlNSmgr = new XmlNamespaceManager(_xmlDocument.NameTable);        

            foreach(XmlNode nsNode in _xmlNameSpaceList)
            {
                _xmlNSmgr.AddNamespace(nsNode.LocalName,nsNode.Value);
            }

任何评论都会感谢您将知识添加到我的KB ... 感谢

答案 2 :(得分:2)

通过简单地检索XmlDocument的NameTable并从中创建XmlNameSpaceManager,可以解决从XmlDocument检索命名空间的基本问题。

但是,如果您希望列出名称空间用于其他目的,则应该查看GetNamespacesInScope类以及XmlNamespaceManager类公开的XPathNavigator方法。

使用XmlDocument时,可以通过以下代码从中获取XmlNamespaceManager:

//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介绍了一种使用此方法使用XPathNavigator并使用LINQ桥来列出文档中所有命名空间的方法。

答案 3 :(得分:2)

Ruchita发布了XmlDocument的工作解决方案。但我想对XDocument做同样的事情。这与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);
}

现在您可以将XPath用于名称空间,例如xml.XPathEvaluate("//test:p", xmlNSmgr)

答案 4 :(得分:-3)

如果您正在寻找避免名称空间问题的快速方法,请在执行XmlDocument.LoadXml(bla)之前通过RegEx将名称空间定义从Xml中删除。我在解析实时XHTML页面时这样做。将XmlDoc的加载时间从15秒加到.15秒,并使其不必为我的xpath添加前缀。