如何从XDocument获取NameTable?

时间:2009-06-01 11:43:32

标签: c# xml xpath linq-to-xml

如何从XDocument获取NameTable?

它似乎没有XmlDocument具有的NameTable属性。

编辑:由于缺乏答案,我猜我可能会忽略这一点。

我正在对像这样的XDocument进行XPath查询......

document.XPathSelectElements("//xx:Name", namespaceManager);

它工作正常,但我必须手动将我想要使用的命名空间添加到XmlNamespaceManager,而不是像使用XmlDocument那样从XDocument中检索现有的命名表。

4 个答案:

答案 0 :(得分:29)

您需要通过XmlReader推送XML并使用XmlReader的NameTable属性。

如果您已经有Xml加载到XDocument中,请确保使用XmlReader加载XDocument: -

XmlReader reader = new XmlTextReader(someStream);
XDocument doc = XDocument.Load(reader);
XmlNameTable table = reader.NameTable;

如果要使用XDocument从头开始构建Xml,则需要调用XDocument的CreateReader方法,然后让某些内容消耗读者。一旦使用了阅读器(比如加载另一个XDocument但更好的是有些什么东西不会导致读者通过XDocument的内容),你可以检索NameTable。

答案 1 :(得分:22)

我是这样做的:

//Get the data into the XDoc
XDocument doc = XDocument.Parse(data);
//Grab the reader
var reader = doc.CreateReader();
//Set the root
var root = doc.Root;
//Use the reader NameTable
var namespaceManager = new XmlNamespaceManager(reader.NameTable);
//Add the GeoRSS NS
namespaceManager.AddNamespace("georss", "http://www.georss.org/georss");  
//Do something with it
Debug.WriteLine(root.XPathSelectElement("//georss:point", namespaceManager).Value);  

马特

答案 2 :(得分:5)

  

我必须手动添加我想要使用的名称空间   XmlNamespaceManager而不是从中检索现有的名称表   XDocument就像你使用XmlDocument一样。

XDocument project = XDocument.Load(path);
//Or: XDocument project = XDocument.Parse(xml);
var nsMgr = new XmlNamespaceManager(new NameTable());
//Or: var nsMgr = new XmlNamespaceManager(doc.CreateReader().NameTable);
nsMgr.AddNamespace("msproj", "http://schemas.microsoft.com/developer/msbuild/2003");
var itemGroups = project.XPathSelectElements(@"msproj:Project/msproj:ItemGroup", nsMgr).ToList();

答案 3 :(得分:1)

它也可以由XPathNavigator完成。当您既不知道Xml文件编码也不知道名称空间前缀时,这很有用。

XDocument xdoc = XDocument.Load(sourceFileName);
XPathNavigator navi = xdoc.Root.CreateNavigator();
XmlNamespaceManager xmlNSM = new XmlNamespaceManager(navi.NameTable);
//Get all the namespaces from navigator
IDictionary<string, string> dict = navi.GetNamespacesInScope(XmlNamespaceScope.All);
//Copy them into Manager
foreach (KeyValuePair<string, string> pair in dict)
{
    xmlNSM.AddNamespace(pair.Key, pair.Value);
}