0

I am trying to obtain the values for the <d:neu_UniqueId> and <d:Name> elements in the XML structure below. The program I'm working on makes a call to a WCF web service and, based upon search criteria input by the user, returns an XML document with a list of this information (I've removed the values for privacy).

<entry>
<id xmlns=\"http://www.w3.org/2005/Atom\">http://quahildy01/xRMDRMA02/XRMServices/2011/OrganizationData.svc</id>
<title type=\"text\" xmlns=\"http://www.w3.org/2005/Atom\">somethingHere</title>
<updated xmlns=\"http://www.w3.org/2005/Atom\">2013-04-24T17:15:45Z</updated>
<author xmlns=\"http://www.w3.org/2005/Atom\"><name /></author>
<link rel=\"edit\" title=\"Account\" href=\"AccountSet(guid'aa2232f4-418a-e111-9710-005056a8161c')\" xmlns=\"http://www.w3.org/2005/Atom\" />
<category term=\"Microsoft.Crm.Sdk.Data.Services.Account\" scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" xmlns=\"http://www.w3.org/2005/Atom\" />
<content type=\"application/xml\" xmlns=\"http://www.w3.org/2005/Atom\">
    <m:properties xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">
        <d:neu_UniqueId xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\">123</d:neu_UniqueId>
        <d:AccountId m:type=\"Edm.Guid\" xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\">1</d:AccountId>
        <d:Name xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\">SomethingInHere</d:Name>
    </m:properties>
</content>
</entry>

Here is the C# code I'm using. when I step through the code, I can see the correct values in childNode variable, however when the program moves over the first .InnerText() method I receive this error:

NullReferenceException: Object reference not set to an instance of an object.

Here is the code

        try
        {
            WebRequest myWebRequest = WebRequest.Create(URL);
            myWebRequest.PreAuthenticate = true;
            myWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;

            WebResponse myWebResponse = myWebRequest.GetResponse();
            Stream myFileStreamResult = myWebResponse.GetResponseStream();
            Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
            StreamReader readStream = new StreamReader(myFileStreamResult, encoder);

            results = readStream.ReadToEnd();

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(results);

            XmlNodeList parentNode = xmlDoc.GetElementsByTagName("entry");

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
            nsmgr.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
            nsmgr.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");

            string accountName2 = xmlDoc.SelectSingleNode("entry/content/m:properties/d:Name", nsmgr).InnerText;

            foreach (XmlNode childNode in parentNode)
            {
                string accountName = childNode.SelectSingleNode("/content/m:properties/d:Name", nsmgr).InnerText;
                string uniqueId = childNode.SelectSingleNode("/content/m:properties/d:neu_UniqueId", nsmgr).InnerText;
            }

        }

EDIT

Looks like this is an issue with the XML being returned from the web service. For each element the xmlns attribute contains a \ character before the value.

9
  • I think that your childNode.SelectSingleNode() statements aren't actually finding the nodes Commented Apr 24, 2013 at 20:34
  • I agree, but I don't understand why. I believe I've set up the namespaces and called the paths correctly. This is my first time parsing XML, however, so I could be wrong. Commented Apr 24, 2013 at 20:37
  • I personally don't have too much esperience dealing with XML namespaces, but I think that it might be the issue. It's a thing that I'd look into Commented Apr 24, 2013 at 20:38
  • I've removed the values for privacy. That is OK, but you can at least post a valid xml with dummy data to work on. Commented Apr 24, 2013 at 20:38
  • If the web service is WCF then why aren't you using WCF to call it? One of the advantages of using the WCF framework is avoiding manual XML parsing; the data is serialized/deserialized for you. Commented Apr 24, 2013 at 20:46

1 Answer 1

1

Try adding a namespace entry for "http://www.w3.org/2005/Atom" and using that in your XPath. Also remove the first '/' character from the XPath in the SelectSingleNode calls within the foreach.

EDIT

I setup the xml in a file named response.xml and it looks like the following. Removed some of the backslashes in yours to make it viable.

<?xml version="1.0" encoding="UTF-8"?>
<entry>
  <id xmlns="http://www.w3.org/2005/Atom">http://quahildy01/xRMDRMA02/XRMServices/2011/OrganizationData.svc</id>
  <title type="text" xmlns="http://www.w3.org/2005/Atom">somethingHere</title>
  <updated xmlns="http://www.w3.org/2005/Atom">2013-04-24T17:15:45Z</updated>
  <author xmlns="http://www.w3.org/2005/Atom">
    <name />
  </author>
  <link rel="edit" title="Account" href="AccountSet(guid'aa2232f4-418a-e111-9710-005056a8161c')" xmlns="http://www.w3.org/2005/Atom" />
  <category term="Microsoft.Crm.Sdk.Data.Services.Account" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" xmlns="http://www.w3.org/2005/Atom" />
  <content type="application/xml" xmlns="http://www.w3.org/2005/Atom">
    <m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
      <d:neu_UniqueId xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">123</d:neu_UniqueId>
      <d:AccountId m:type="Edm.Guid" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">1</d:AccountId>
      <d:Name xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">SomethingInHere</d:Name>
    </m:properties>
  </content>
</entry>

I read in the file and parsed it with the below code and it worked for me.

        string path = @"response.xml";
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(path);

        XmlNodeList parentNode = xmlDoc.GetElementsByTagName("entry");

        XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
        nsmgr.AddNamespace("f", "http://www.w3.org/2005/Atom");
        nsmgr.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
        nsmgr.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");

        var accountName2 = xmlDoc.SelectSingleNode("entry/f:content/m:properties/d:Name", nsmgr).InnerText;

        foreach (XmlNode childNode in parentNode)
        {
            string accountName = childNode.SelectSingleNode("f:content/m:properties/d:Name", nsmgr).InnerText;
            string uniqueId = childNode.SelectSingleNode("f:content/m:properties/d:neu_UniqueId", nsmgr).InnerText;
        }
Sign up to request clarification or add additional context in comments.

2 Comments

Edited my code above so you can have some working code. If it doesn't work perhaps it is due to the XML example being off slightly. Hope this helps
As an ugly fix if you can't get valid XML back from teh web service you could do results = results.Replace("\\\"","\""); put that right before you load it into the XmlDocument and it will remove that problem of the \ by the xmlns

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.