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") ...