1

I'm trying to parse an XML response from a REST endpoint. I am using a POST request (if that's relevant). I can't get the document to parse correctly. I've researched this all over stack overflow, and none seem to be applicable to my response. How can i parse my XML? I've tried all of the below:

Using XDocument:

Stream postData = resp.GetResponseStream();
StreamReader reader = new StreamReader(postData, Encoding.UTF8);
string result = reader.ReadToEnd();
var document = XDocument.Parse(result);
XNamespace ns = XNamespace.Get("http://www.w3.org/2005/Atom");
var items = document.Descendants("NameFirst")
                    .ToDictionary(i => (string)i.Attribute("Key"),
                                  i => (string)i.Attribute("Value"));

Using nested for each with XElements:

Stream postData = resp.GetResponseStream();
StreamReader reader = new StreamReader(postData, Encoding.UTF8);
string result = reader.ReadToEnd();
XDocument document = XDocument.Parse(result);
XNamespace ns = XNamespace.Get("http://www.w3.org/2005/Atom");
string list = "";
foreach (XElement level1 in document.Elements("feed"))
{
    foreach (XElement level2 in level1.Elements("entry"))
    {
        foreach (XElement level3 in level2.Elements("content"))
        {
            foreach (XElement entry in level3.Elements("Entry"))
            {
                list += entry.Attribute("NameFirst").Value;
                list += entry.Attribute("NameLast").Value;
            }
        }
    }
}

Using a concatenation of Descendant methods:

Stream postData = resp.GetResponseStream();
StreamReader reader = new StreamReader(postData, Encoding.UTF8);
string result = reader.ReadToEnd();
var document = XDocument.Parse(result);
XNamespace ns = XNamespace.Get("http://www.w3.org/2005/Atom");
var listOfFields = document.Descendants(ns + "feed").Descendants(ns + "entry").Descendants(ns + "content").Descendants(ns + "entry").Select(x => x.Elements().First().Value).ToList();
ResultLabel.Text = "";
foreach(String item in listOfFields){
    ResultLabel.Text += item;
}

Using multiple Element methods:

Stream postData = resp.GetResponseStream();
StreamReader reader = new StreamReader(postData, Encoding.UTF8);
string result = reader.ReadToEnd();
var document = XDocument.Parse(result);
XNamespace ns = XNamespace.Get("http://www.w3.org/2005/Atom");
var listOfFields = document.Descendants(ns + "feed").Descendants(ns + "entry").Descendants(ns + "content").Descendants(ns + "entry").Select(x => x.Elements().First().Value).ToList();
var entry_ = document.Root.Element("entry");
var content = entry_.Element("content");
var entry = content.Element("Entry");
var fname = entry.Element("NameFirst").Value;
var lname = entry.Element("NameLast").Value;
ResultLabel.Text = string.Join(",", lname, fname);

My XML response:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title type="text">Search Results</title>
    <id>https://myendpoint.com/Rest/services/select/Entry</id>
    <updated>2015-10-07T09:51:32Z</updated>
    <link rel="self" type="application/atom+xml" href="https://myendpoint.com/Rest/services/select/Entry" />
    <entry>
        <id>https://myendpoint.com/services/select/Entry/26032</id>
        <title type="text">Smith, John</title>
        <published>2013-10-08T10:14:20Z</published>
        <updated>2015-10-02T12:14:18Z</updated>
        <contributor><name>WebUser</name></contributor>
            <content type="xhtml">
            <Entry>
                <EntryID>26032</EntryID>
                <CategoryID>0</CategoryID>
                <EventID>0</EventID>
                <GroupID>0</GroupID>
                <ContactID>0</ContactID>
                <AddressTypeID>0</AddressTypeID>
                <PinNumber>0000</PinNumber>
                <Password></Password>
                <PortalEmail></PortalEmail>
                <NameLast>Smith</NameLast>
                <NameFirst>John</NameFirst>
                <NameTitle></NameTitle>
                <NamePreferred>Mike</NamePreferred>
                <NameWeb>smith</NameWeb>
                <NameOther></NameOther>
                <NameInitials></NameInitials>
                <NameSharer></NameSharer>
                <GenderEnum>Female</GenderEnum>
                <Birth_GenderEnum>Male</Birth_GenderEnum>
                <DirectoryFlagPrivacy>false</DirectoryFlagPrivacy>
                <Position></Position>
                <ID1>123456</ID1>
                <ID2>smith</ID2>
                <ID3></ID3>
                <ID4>0</ID4>
                <ID5>0</ID5>
                <PhoneProcessToAccount>true</PhoneProcessToAccount>
                <PhoneChargeTypeID>0</PhoneChargeTypeID>
                <PhoneDisableValue>0</PhoneDisableValue>
                <PhoneRestrictValue>0</PhoneRestrictValue>
                <PhoneControlEnum>Default</PhoneControlEnum>
                <TaxExemptionEnum>None</TaxExemptionEnum>
                <Testing>true</Testing>
                <timestamp>000007975236</timestamp>
            </Entry>
        </content>
    </entry>
</feed>
2
  • @vendettamit it doesn't parse anything. The XDocument is the only thing that has any data within the variables. Everything underneath it is blank. Commented Oct 16, 2015 at 16:57
  • This is atom feed. If you search on internet you can find parser libraries that will save you some time. Commented Oct 16, 2015 at 16:59

1 Answer 1

5

You can deserialize the XML into easily accessible objects. Here's how to do it:

Create the objects that will hold your deserialized data:

You can easily do it by copying the XML you're getting from your REST endpoint then in Visual Studio go to Edit -> Paste Special -> Paste XML as classes

enter image description here

Once your classes are created you will get something like this:

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/Atom")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2005/Atom", IsNullable = false)]
public partial class feed
{

    public feedTitle title { get; set; }

    public string id { get; set; }

    public System.DateTime updated { get; set; }

    public feedLink link { get; set; }

    public feedEntry entry { get; set; }
}


[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/Atom")]
public partial class feedTitle
{
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string type { get; set; }

    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value { get; set; }
}


[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/Atom")]
public partial class feedLink
{
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string rel { get; set; }

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string type { get; set; }

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string href { get; set; }
}


[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/Atom")]
public partial class feedEntry
{

    public string id { get; set; }

    public feedEntryTitle title { get; set; }

    public System.DateTime published { get; set; }

    public System.DateTime updated { get; set; }

    public feedEntryContributor contributor { get; set; }

    public feedEntryContent content { get; set; }
}


[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/Atom")]
public partial class feedEntryTitle
{

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string type { get; set; }

    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value { get; set; }
}


[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/Atom")]
public partial class feedEntryContributor
{

    public string name { get; set; }
}


[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/Atom")]
public partial class feedEntryContent
{

    public feedEntryContentEntry Entry { get; set; }

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string type { get; set; }
}


[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/Atom")]
public partial class feedEntryContentEntry
{

    public ushort EntryID { get; set; }

    public byte CategoryID { get; set; }

    public byte EventID { get; set; }

    public byte GroupID { get; set; }

    public byte ContactID { get; set; }

    public byte AddressTypeID { get; set; }

    public byte PinNumber { get; set; }

    public object Password { get; set; }

    public object PortalEmail { get; set; }

    public string NameLast { get; set; }

    public string NameFirst { get; set; }

    public object NameTitle { get; set; }

    public string NamePreferred { get; set; }

    public string NameWeb { get; set; }

    public object NameOther { get; set; }

    public object NameInitials { get; set; }

    public object NameSharer { get; set; }

    public string GenderEnum { get; set; }

    public string Birth_GenderEnum { get; set; }

    public bool DirectoryFlagPrivacy { get; set; }

    public object Position { get; set; }

    public uint ID1 { get; set; }

    public string ID2 { get; set; }

    public object ID3 { get; set; }

    public byte ID4 { get; set; }

    public byte ID5 { get; set; }

    public bool PhoneProcessToAccount { get; set; }

    public byte PhoneChargeTypeID { get; set; }

    public byte PhoneDisableValue { get; set; }

    public byte PhoneRestrictValue { get; set; }

    public string PhoneControlEnum { get; set; }

    public string TaxExemptionEnum { get; set; }

    public bool Testing { get; set; }

    public uint timestamp { get; set; }
}

Then you can deserialize the XML into a feed object like the following:

using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("Your XML string here")))
{
    XmlSerializer serializer = new XmlSerializer(typeof(feed));
    feed feedObject = (feed)serializer.Deserialize(ms);

    // Then you can access the xml content like you do with any object.
    Console.WriteLine(feedObject.title.Value);
}

Live demo

Sign up to request clarification or add additional context in comments.

Comments

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.