Reading xml string with c#

I have the following soap response string:

<EncryptionInfoResponse> <Status>0</Status> <Message></Message> <ServiceID>xxxxxxx</ServiceID> <KeyID>xxxxxxxxx</KeyID> <ContentKey>xxxxxxx</ContentKey> <LicAcqURL><![CDATA[http://sldrm.licensekeyserver.com/core/rightsmanager.asmx]]></LicAcqURL> <LicUIURL></LicUIURL> <CustomXML><![CDATA[<CID>pFRCPIy87oUJtOWis7IYAA==</CID><DRMTYPE>smooth</DRMTYPE>]]></CustomXML> <ContentID>xxxxxxx</ContentID> <PRHeader><![CDATA[<WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.0.0.0"><DATA><PROTECTINFO><KEYLEN>16</KEYLEN><ALGID>AESCTR</ALGID></PROTECTINFO><KID>xvd10JPbxh5rsS27LoCIxQ==</KID><LA_URL>http://sldrm.licensekeyserver.com/core/rightsmanager.asmx</LA_URL><DS_ID>xxxxxx</DS_ID><CUSTOMATTRIBUTES xmlns=""><CID>pFRCPIy87oUJtOWis7IYAA==</CID><DRMTYPE>smooth</DRMTYPE></CUSTOMATTRIBUTES><CHECKSUM>GKaxxISZpMs=</CHECKSUM></DATA></WRMHEADER>]]></PRHeader> </EncryptionInfoResponse>

I want to get the values of "KeyID" and "ContentKey" attributes. I have tried the following below with no success, I got "Sequence contains no elements" error:

string str = Utility.ReadTextFromUrl(ConfigurationManager.AppSettings["SoapUrl"]);
XElement xdoc = XElement.Parse(str);
string result = xdoc.Descendants("EncryptionInfoResponse")
                    .Descendants("KeyID")                       
                    .First()
                    .Value;
return result;

How do I do this?

---- Edit --------------

I figured out that the problem will be the string from the URL which is a PHP script sending request to a soap service. So I wrote a Soap request with C# and was able to get response body of the soap:

using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
        using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
        {
                soapResult = rd.ReadToEnd();
        }
        System.Diagnostics.Debug.WriteLine(soapResult);
        XDocument xDoc = XDocument.Load(new StringReader(soapResult));

      var unwrappedResponse = xDoc.Descendants((XNamespace)"http://schemas.xmlsoap.org/soap/envelope/" + "Body")
                    .First()
                    .FirstNode;
       System.Diagnostics.Debug.WriteLine(unwrappedResponse);

}

But I got stuck here, I have not been able to read the KeyID and ContentKey nodes, this is the response body:

<RequestEncryptionInfoResponse xmlns="http://tempuri.org/">
  <RequestEncryptionInfoResult>&lt;EncryptionInfoResponse&gt;
  &lt;Status&gt;0&lt;/Status&gt;
  &lt;Message&gt;&lt;/Message&gt;
  &lt;ServiceID&gt;xxxx-xxxx-xxx-xxx&lt;/ServiceID&gt;
  &lt;KeyID&gt;xxxx-xxxx-xxx-xxx&lt;/KeyID&gt;
  &lt;ContentKey&gt;KXnH9nzdDbW6kIw11yvY8A==&lt;/ContentKey&gt;
  &lt;LicAcqURL&gt;&lt;![CDATA[http://sldrm.licensekeyserver.com/core/rightsmanager.asmx]]&gt;&lt;/LicAcqURL&gt;
  &lt;LicUIURL&gt;&lt;/LicUIURL&gt;
  &lt;CustomXML&gt;&lt;![CDATA[&lt;CID&gt;RMgchjQPQS+zfHTzsPGSsQ==&lt;/CID&gt;&lt;DRMTYPE&gt;smooth&lt;/DRMTYPE&gt;]]&gt;&lt;/CustomXML&gt;
  &lt;ContentID&gt;861cc844-0f34-2f41-b37c-74f3b0f192b1&lt;/ContentID&gt;
  &lt;PRHeader&gt;&lt;![CDATA[&lt;WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.0.0.0"&gt;&lt;DATA&gt;&lt;PROTECTINFO&gt;&lt;KEYLEN&gt;16&lt;/KEYLEN&gt;&lt;ALGID&gt;AESCTR&lt;/ALGID&gt;&lt;/PROTECTINFO&gt;&lt;KID&gt;ZEjIHDgPQI+zffOw8ZJ0sQ==&lt;/KID&gt;&lt;LA_URL&gt;http://sldrm.licensekeyserver.com/core/rightsmanager.asmx&lt;/LA_URL&gt;&lt;DS_ID&gt;VlR7IdsIJEuRd06Laqs2jw==&lt;/DS_ID&gt;&lt;CUSTOMATTRIBUTES xmlns=""&gt;&lt;CID&gt;RMgchjQPQS+zfHTzsPGSsQ==&lt;/CID&gt;&lt;DRMTYPE&gt;smooth&lt;/DRMTYPE&gt;&lt;/CUSTOMATTRIBUTES&gt;&lt;CHECKSUM&gt;/ytWga+hG9o=&lt;/CHECKSUM&gt;&lt;/DATA&gt;&lt;/WRMHEADER&gt;]]&gt;&lt;/PRHeader&gt;
&lt;/EncryptionInfoResponse&gt;</RequestEncryptionInfoResult>
</RequestEncryptionInfoResponse>

any help?

Jon Skeet
people
quotationmark

The problem is that you're using XElement.Parse, so you're parsing the string as an element... so xdoc is already the EncryptionInfoResponse element, which doesn't have any more EncryptionInfoResponse descendants.

Options:

  • Use XDocument.Parse instead, so you end up with a document with an EncryptionInfoResponse element under it
  • Get rid of the Descendants("EncryptionInfoResponse") call, but keep the rest as it is.

Given that the KeyID is a direct child, you could make this simpler using Element(...) instead of Descendants(...).First().

XElement root = XElement.Parse(str);
string result = root.Element("KeyID").Value;

people

See more on this question at Stackoverflow