使用XmlDocument从带或不带命名空间的xml文件中读取

我有一些代码使用XmlDocument从带有命名空间的xml文件读取。我的挑战是我有文件的命名空间我现在正在阅读硬编码并且我将它传递给XmlNamespaceManager.I希望我的方法是从任何类型的xml文件读取。如果它有一个命名空间,那么使用命名空间管理器来读取元素而无需对命名空间进行硬编码。如果文件没有命名空间,那么请继续解析它。我就是这样做的。

xmldoc = new XmlDocument (); xmldoc.Load (fileLocation); XmlNamespaceManager nameSpaceManager = new XmlNamespaceManager(xmldoc.NameTable); nameSpaceManager.AddNamespace ("ns","http://schemas.sample.data.org/2005"); XmlNodeList nodeList = xmldoc.SelectNodes("/ns:Demo/ns:Items", nameSpaceManager); if (nodeList != null) { foreach (XmlNode childNode in nodeList) { string first = childNode.SelectSingleNode ("ns:First", nameSpaceManager).InnerText; string second= childNode.SelectSingleNode ("ns:Second", nameSpaceManager).InnerText; string third = childNode.SelectSingleNode ("ns:Third", nameSpaceManager).InnerText; } } 

这是我正在使用的示例xml文件

   first second third   

您可以考虑以下选项:

  1. 确定文档是否包含命名空间,并根据它构造xpath查询
  2. 使用名称空间不可知的xpath,例如local-name() ,它将忽略名称空间

选项1

 var xmlDoc = new XmlDocument(); xmlDoc.Load(fileLocation); //determine whether document contains namespace var namespaceName = "ns"; var namespacePrefix = string.Empty; XmlNamespaceManager nameSpaceManager = null; if (xmlDoc.FirstChild.Attributes != null) { var xmlns = xmlDoc.FirstChild.Attributes["xmlns"]; if (xmlns != null) { nameSpaceManager = new XmlNamespaceManager(xmlDoc.NameTable); nameSpaceManager.AddNamespace(namespaceName, xmlns.Value); namespacePrefix = namespaceName + ":"; } } XmlNodeList nodeList = xmlDoc.SelectNodes(string.Format("/{0}Demo/{0}Items",namespacePrefix), nameSpaceManager); if (nodeList != null) { foreach (XmlNode childNode in nodeList) { string first = childNode.SelectSingleNode(namespacePrefix + "First", nameSpaceManager).InnerText; string second = childNode.SelectSingleNode(namespacePrefix + "Second", nameSpaceManager).InnerText; string third = childNode.SelectSingleNode(namespacePrefix + "Third", nameSpaceManager).InnerText; } } 

选项2

 XmlNodeList nodeList = xmlDoc.SelectNodes("/*[local-name() = 'Demo']/*[local-name() = 'Items']"); if (nodeList != null) { foreach (XmlNode childNode in nodeList) { string first = childNode.SelectSingleNode("*[local-name() = 'First']").InnerText; string second = childNode.SelectSingleNode("*[local-name() = 'Second']").InnerText; string third = childNode.SelectSingleNode("*[local-name() = 'Third']").InnerText; } } 

使用Linq-to-XML和我的库扩展 ,特别是内部处理的ToXName ,您可以:

 XElement root = XElement.Load(fileLocation); var items = root.Descendants("Items") .Select(item => new { First = item.Get("First", ""), Second= item.Get("Second", ""), Third = item.Get("Third", "") }); 

因此,每个FirstSecondThird元素都将使用Items元素的命名空间来确定自己的命名空间。