Xml Document Selectsinglenode Returns Null

Xml Document Selectsinglenode Returns Null

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.

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

<RateQuoteResponse xmlns="">
  <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>
0

5 Answers

The XML document uses the default namespace "". You need to change the SelectSingleNode call to use this namespace.

You need to setup a namspace manager and then supply it to SelectSingleNode.

var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("rate", "");
var node = xmlDocument.SelectSingleNode("//rate:RateQuote", nsmgr);

EDIT The RateQuoteResponse element has a default namespace xmlns="...". This means that all elements use this namespace also, unless specifically overridden.

7

You can remove the namespace while reading the file, just disable the namespaces on the 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.

1

The problem is that you're asking for a RateQuote element without a namespace - whereas the RateQuote element is actually in the namespace with URI .

You can either use an XmlNamespaceManager to address the namespace within your XPath, or use LINQ to XML which has very simple namespace handling:

var document = XDocument.Load(stream);
XNamespace ns = "";
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.

EDIT: Note that the namespace defaulting applies to child elements too. So to find the TOTAL_COST element you'd need:

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

You might want to set Namespaces to false in the XmlTextReader.

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.

You should also be able to do:

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

The VB syntax for that is:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

James H. Sterling
Author

James H. Sterling

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.