33

我正在尝试从流阅读器中读取 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 文档

<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>
4

5 回答 5

58

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="..."。这意味着所有元素也使用这个命名空间,除非被特别覆盖。

于 2013-06-18T05:44:40.407 回答
15

您可以在读取文件时删除命名空间,只需禁用 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 时,您不必关心命名空间。

于 2014-11-05T17:56:28.877 回答
9

问题是您要的是RateQuote没有命名空间的元素 - 而该RateQuote元素实际上位于具有 URI 的命名空间中http://ratequote.usfnet.usfc.com/v2/x1

您可以使用anXmlNamespaceManager来处理 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");
于 2013-06-18T05:45:19.647 回答
6

您可能希望在 XmlTextReader 中将命名空间设置为false

因此,在您的代码中,更改:

var xmlReader = new XmlTextReader(stream);

var xmlReader = new XmlTextReader(stream) { Namespaces = false };

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

于 2016-08-23T16:58:21.330 回答
3

您还应该能够:

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

VB 的语法是:

...
Dim node as XmlNode = xmlDocument("RateQuote")
...
于 2015-10-20T07:59:22.000 回答