XML Document SelectSingleNode返回null

我试图从流阅读器读取XML,并且还获得响应XML。 但是当我尝试读取它的节点时,它总是返回null。

var request = (HttpWebRequest) WebRequest.Create(address); var response = (HttpWebResponse) request.GetResponse(); var stream = response.GetResponseStream(); if(stream != null) { var xmlReader = new XmlTextReader(stream); var xmlDocument = new XmlDocument(); xmlDocument.Load(xmlReader); var node = xmlDocument.SelectSingleNode("RateQuote"); } 

XML文档

   0 SECURED ...    KNOXVILLE USF Holland, Inc 
5409 N NATIONAL DR
KNOXVILLE TN 37914 8664655263 8006545963 8656379999 KNOXVILLE USF Holland, Inc
5409 N NATIONAL DR
KNOXVILLE TN 37914 8664655263 8006545963 8656379999 37914 37909 99.24 1 1.6 55 50 100 0.0

XML文档使用默认命名空间“ http://ratequote.usfnet.usfc.com/v2/x1 ”。 您需要更改SelectSingleNode调用以使用此命名空间。

您需要设置一个namspace管理器,然后将其提供给SelectSingleNode

 var nsmgr = new XmlNamespaceManager(doc.NameTable); nsmgr.AddNamespace("rate", "http://ratequote.usfnet.usfc.com/v2/x1"); var node = xmlDocument.SelectSingleNode("//rate:RateQuote", nsmgr); 

编辑 RateQuoteResponse元素具有默认名称空间xmlns="..." 。 这意味着除非特别重写,否则所有元素也会使用此命名空间。

您可以在读取文件时删除命名空间,只需禁用XmlTextReader上的命名空间:

 var request = (HttpWebRequest) WebRequest.Create(address); var response = (HttpWebResponse) request.GetResponse(); var stream = response.GetResponseStream(); if(stream != null) { var xmlReader = new XmlTextReader(stream); xmlReader.Namespaces = false; var xmlDocument = new XmlDocument(); xmlDocument.Load(xmlReader); var node = xmlDocument.SelectSingleNode("RateQuote"); } 

之后,在XML元素上使用XPath / LINQ时,您不必关心命名空间。

问题是你要求一个没有命名空间的RateQuote元素 – 而RateQuote元素实际上是在URI的http://ratequote.usfnet.usfc.com/v2/x1的命名空间中。

您可以使用XmlNamespaceManager来解决XPath中的命名空间,也可以使用LINQ to XML,它具有非常简单的命名空间处理:

 var document = XDocument.Load(stream); XNamespace ns = "http://ratequote.usfnet.usfc.com/v2/x1"; XElement rateQuote = document.Root.Element(ns + "RateQuote"); 

我个人会尽可能使用LINQ to XML – 我发现使用它比XmlDocument更令人愉快。 如果你想要的话,你仍然可以使用XPath,但我个人更喜欢使用查询方法。

编辑:请注意,名称空间默认也适用于子元素。 所以要找到你需要的TOTAL_COST元素:

 XElement cost = document.Root .Element(ns + "RateQuote") .Element(ns + "TOTAL_COST"); 

更改:

 var xmlReader = new XmlTextReader(stream); var xmlDocument = new XmlDocument(); xmlDocument.Load(xmlReader); 

 var xmlReader = new XmlTextReader(stream) { Namespaces = false }; var xmlDocument = new XmlDocument(); xmlDocument.Load(xmlReader); 

但是……你也可以改进一下代码,并使用类似的东西:

 var xmlDocument = new XmlDocument(); xmlDocument.Load(new XmlTextReader(stream) { Namespaces = false }); 

如果您更喜欢从数据XML字符串加载,您可以使用:

 var xmlDocument = new XmlDocument(); xmlDocument.Load(new XmlTextReader(new StringReader(data)) { Namespaces = false }); 

通过此更改,您应该能够使用SelectSingleNode获取所需的节点,而无需使用命名空间。

你也应该能够做到:

 ... var node = xmlDocument["RateQuote"]; ... 

这个的VB语法是:

 ... Dim node as XmlNode = xmlDocument("RateQuote") ...