C# 如何在 XML 中列出所有命名空间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/767541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how i can list out all the namespace in XML?
提问by
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.
我的基本要求是从 XML 文件中获取元素值,我使用了 XMLDoxument.SelectSingleNode。我的 XML 文件在标题中包含一些命名空间,因此我使用 NameSpaceManager 添加命名空间前缀,并使用前缀来获取该特定元素。现在,在我的 XML 文件中,命名空间正在发生变化,我不想进行任何硬编码,有什么方法可以找出所有命名空间并将其添加到 NameSpaceManager.xml 中。
Thanks.
谢谢。
回答by Cerebrus
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.
从 XmlDocument 检索命名空间的基本问题可以通过简单地检索NameTable
XmlDocument 的 并XmlNameSpaceManager
从中创建一个来解决。
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.
但是,如果您想出于其他目的列出命名空间,则应该检查类以及类GetNamespacesInScope
公开的方法。XmlNamespaceManager
XPathNavigator
When using an XmlDocument, you can get an XmlNamespaceManager from it via the following code:
使用 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 presents a way to use this method to list all namespaces in a document using an XPathNavigator and using a LINQ bridge.
在本文中,Scott Hanselman 展示了一种使用此方法使用 XPathNavigator 和使用 LINQ 桥列出文档中的所有名称空间的方法。
回答by Cerebrus
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 :( ..
我认为您使用的 .Net 版本必须是最新版本。我正在使用 .Net 框架 1.1 ......很老:(..
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
任何评论将不胜感激,为我的知识库增加知识......谢谢
回答by Edward
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.
如果您正在寻找避免命名空间问题的快速方法,请在执行 XmlDocument.LoadXml(bla) 之前通过 RegEx 从 Xml 中删除命名空间定义。我在解析实时 XHTML 页面时这样做。将 XmlDoc 加载时间从 15 秒缩短到 0.15 秒,这样我就不必为我的 xpath 加上前缀。
回答by sammybar
Namespaces can be found anywhere inside xml document. So to extract all namespaces and declare them into a XmlNamespaceManager I did the following:
命名空间可以在 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;
}
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
只需注意默认命名空间的情况。我将默认命名空间重新定义为“DEFAULT”前缀,因为在查询默认命名空间时使用上述返回的命名空间管理器创建 SelectSingleNode 时遇到问题。我是我的解决方法。希望这可以帮助
回答by Carsten Franke
Ruchita posted the working solution for XmlDocument
. But I wanted to do the same with XDocument
. Here is the very same with XDocument
:
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);
}
Now you can use XPath with namespaces, e.g. xml.XPathEvaluate("//test:p", xmlNSmgr)
.
现在您可以将 XPath 与命名空间一起使用,例如xml.XPathEvaluate("//test:p", xmlNSmgr)
.