C# XML 文档 SelectSingleNode 返回 null
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17161317/
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
XML Document SelectSingleNode returns null
提问by
I am trying to read XML from stream reader and am also getting response XML. But when i try to read its nodes it is always returning 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 Document
XML 文件
<RateQuoteResponse xmlns="http://ratequote.usfnet.usfc.com/v2/x1">
<STATUS>
<CODE>0</CODE>
<VIEW>SECURED</VIEW>
<VERSION>...</VERSION>
</STATUS>
<RateQuote>
<ORIGIN>
<NAME>KNOXVILLE</NAME>
<CARRIER>USF Holland, Inc</CARRIER>
<ADDRESS>5409 N NATIONAL DR</ADDRESS>
<CITY>KNOXVILLE</CITY>
<STATE>TN</STATE>
<ZIP>37914</ZIP>
<PHONE>8664655263</PHONE>
<PHONE_TOLLFREE>8006545963</PHONE_TOLLFREE>
<FAX>8656379999</FAX>
</ORIGIN>
<DESTINATION>
<NAME>KNOXVILLE</NAME>
<CARRIER>USF Holland, Inc</CARRIER>
<ADDRESS>5409 N NATIONAL DR</ADDRESS>
<CITY>KNOXVILLE</CITY>
<STATE>TN</STATE>
<ZIP>37914</ZIP>
<PHONE>8664655263</PHONE>
<PHONE_TOLLFREE>8006545963</PHONE_TOLLFREE>
<FAX>8656379999</FAX>
</DESTINATION>
<ORIGIN_ZIP>37914</ORIGIN_ZIP>
<DESTINATION_ZIP>37909</DESTINATION_ZIP>
<TOTAL_COST>99.24</TOTAL_COST>
<SERVICEDAYS>1</SERVICEDAYS>
<INDUSTRYDAYS>1.6</INDUSTRYDAYS>
<CLASSWEIGHT>
<CLASS>55</CLASS>
<ASCLASS>50</ASCLASS>
<WEIGHT>100</WEIGHT>
<CHARGES>0.0</CHARGES>
</CLASSWEIGHT>
</RateQuote>
</RateQuoteResponse>
采纳答案by Richard Schneider
The XML document uses the default namespace "http://ratequote.usfnet.usfc.com/v2/x1". You need to change the SelectSingleNodecall to use this namespace.
XML 文档使用默认命名空间“ http://ratequote.usfnet.usfc.com/v2/x1”。您需要更改SelectSingleNode调用以使用此命名空间。
You need to setup a namspace manager and then supply it to 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);
EDITThe RateQuoteResponseelement has a default namespace xmlns="...". This means that all elements use this namespace also, unless specifically overridden.
编辑该RateQuoteResponse元素有一个默认的命名空间xmlns="..."。这意味着所有元素也使用这个命名空间,除非被特别覆盖。
回答by Jon Skeet
The problem is that you're asking for a RateQuoteelement without a namespace - whereas the RateQuoteelement is actuallyin the namespace with URI http://ratequote.usfnet.usfc.com/v2/x1.
问题是您要求一个RateQuote没有命名空间的RateQuote元素- 而该元素实际上位于带有 URI 的命名空间中http://ratequote.usfnet.usfc.com/v2/x1。
You can eitheruse an XmlNamespaceManagerto address the namespace within your XPath, or use LINQ to XML which has very simple namespace handling:
您可以任意使用XmlNamespaceManager,解决您的XPath内的命名空间,或使用LINQ到XML具有非常简单的命名空间的处理:
var document = XDocument.Load(stream);
XNamespace ns = "http://ratequote.usfnet.usfc.com/v2/x1";
XElement rateQuote = document.Root.Element(ns + "RateQuote");
Personally I would use LINQ to XML if you possibly can - I find it much more pleasant to use than XmlDocument. You can still use XPath if you want of course, but I personally prefer to use the querying methods.
如果可能的话,我个人会使用 LINQ to XML - 我发现它比XmlDocument. 当然,如果您愿意,您仍然可以使用 XPath,但我个人更喜欢使用查询方法。
EDIT: Note that the namespace defaulting applies to child elements too. So to find the TOTAL_COSTelement you'd need:
编辑:请注意,命名空间默认值也适用于子元素。所以要找到TOTAL_COST你需要的元素:
XElement cost = document.Root
.Element(ns + "RateQuote")
.Element(ns + "TOTAL_COST");
回答by Florian D.
You can remove the namespace while reading the file, just disable the namespaces on the XmlTextReader:
您可以在读取文件时删除命名空间,只需禁用 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");
}
After that you don't have to care about the namespace while using XPath / LINQ on your XML-elements.
之后,在 XML 元素上使用 XPath/LINQ 时不必关心命名空间。
回答by mormegil
You should also be able to do:
您还应该能够:
...
var node = xmlDocument["RateQuote"];
...
The VB syntax for that is:
VB 的语法是:
...
Dim node as XmlNode = xmlDocument("RateQuote")
...
回答by Filipe Camizao Lage
You might want to set Namespacesto falsein the XmlTextReader.
您可能希望在 XmlTextReader中将Namespaces设置为false。
So, in your code, change:
因此,在您的代码中,更改:
var xmlReader = new XmlTextReader(stream);
to
到
var xmlReader = new XmlTextReader(stream) { Namespaces = false };
With this change, you should be able to get the node you want with SelectSingleNode without having to use namespaces.
通过此更改,您应该能够使用 SelectSingleNode 获得所需的节点,而无需使用名称空间。

