NickH48226
NickH48226

Reputation: 147

Read xml attribute in C#

I have been searching this for a while and cannot find a solution. I have an xml that is returned from a HttpWebRequest that I load into an xmldocument and I am trying to get a specific attribute (status) of the request. The xml that is returned is below.

<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  >
  <soapenv:Body>
    <processRequestResponse>
      <parameters>
        <ns1:searchResponse status="success" xmlns:ns1="urn:oasis:names:tc:SPML:2:0:search">
          <ns1:pso>
            <ns2:psoID ID="Users:####" xmlns:ns2="urn:oasis:names:tc:SPML:2:0"/>
            <ns3:data xmlns:ns3="urn:oasis:names:tc:SPML:2:0">
              <ns4:attr name="Users.User ID" xmlns:ns4="urn:oasis:names:tc:DSML:2:0:core">
                <ns4:value></ns4:value>
              </ns4:attr>
            </ns3:data>
          </ns1:pso>
        </ns1:searchResponse>
      </parameters>
    </processRequestResponse>
  </soapenv:Body>
</soapenv:Envelope>

My code that I am using to get this data is below.

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string returnResponse = reader.ReadToEnd();

XmlDocument doc = new XmlDocument();
doc.LoadXml(returnResponse);

XmlNode root = doc.DocumentElement;
XmlNode searchResponse = root.SelectSingleNode("Envelope/Body/processRequestResponse/parameters/searchResponse");
XmlAttribute status = (XmlAttribute)searchResponse.Attributes.GetNamedItem("status");
if (status != null)
{
    string statusReturn = status.Value;
    return statusReturn;
}
else
{
    return "value is null";
}

Any help you can give in the status value would be appreciated. I keep getting an object reference error at the xmlattrbute status line.

Upvotes: 0

Views: 1312

Answers (2)

Jesse C. Slicer
Jesse C. Slicer

Reputation: 20157

Try this on for size:

        const string ValueIsNull = "value is null";
        string returnResponse;

        using (var response = (HttpWebResponse)request.GetResponse())
        {
            if (response == null)
            {
                return ValueIsNull;
            }

            using (var responseStream = response.GetResponseStream())
            {
                if (responseStream == null)
                {
                    return ValueIsNull;
                }

                using (var reader = new StreamReader(responseStream))
                {
                    returnResponse = reader.ReadToEnd();
                }
            }
        }

        var doc = new XmlDocument();

        doc.LoadXml(returnResponse);

        var namespaces = new XmlNamespaceManager(doc.NameTable);

        namespaces.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
        namespaces.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
        namespaces.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
        namespaces.AddNamespace("ns1", "urn:oasis:names:tc:SPML:2:0:search");
        namespaces.AddNamespace("ns2", "urn:oasis:names:tc:SPML:2:0");
        namespaces.AddNamespace("ns3", "urn:oasis:names:tc:SPML:2:0");
        namespaces.AddNamespace("ns4", "urn:oasis:names:tc:DSML:2:0:core");

        XmlNode root = doc.DocumentElement;

        if (root == null)
        {
            return ValueIsNull;
        }

        var searchResponse = root.SelectSingleNode("/soapenv:Envelope/soapenv:Body/processRequestResponse/parameters/ns1:searchResponse", namespaces);

        if ((searchResponse == null) || (searchResponse.Attributes == null))
        {
            return ValueIsNull;
        }

        var status = (XmlAttribute)searchResponse.Attributes.GetNamedItem("status");

        return status == null ? ValueIsNull : status.Value;

Upvotes: 0

Michael Edenfield
Michael Edenfield

Reputation: 28338

Your XML document includes namespaces. You will need to account for the namespaces in the XML document before any XPath queries will work.

See this question for how to add these namespaces in your C# code and reference them in your XPath; or see this question for how to use wildcard matching (though in your case that's going to get messy, since you have to do it for every element name.)

Upvotes: 3

Related Questions