Aaron McKelvie
Aaron McKelvie

Reputation: 167

Accessing Elements from multi-level (nested) XML documents in c#

I am pulling XML data from a server using an API and use LINQ to store the results in an anonymous object list, however some of the data is returning "null" and I figured it must be due to the XML document heirarchy. See below-

<export type="orderexport" date="13/01/2015" time="5:01:18 PM">
  <order>
    <OrderNumber>149612</OrderNumber>
    <CustomerNumber>146538</CustomerNumber>
    <Currency>AUD</Currency>
    <Locale>en_AU</Locale>
    <GrandTotal>1548.98</GrandTotal>
    <TotalBeforeTax>1411.58</TotalBeforeTax>
    <TotalTax>137.4</TotalTax>
    <Addresses>
      <BillingAddress>
        <Email>[email protected]</Email>
      </BillingAddress>
      <ShippingAddress>
        <Email>[email protected]</Email>
      </ShippingAddress>
    </Addresses>
    <LineItems>
      <LineItem>...</LineItem>
      <LineItemSalesDiscount>...</LineItemSalesDiscount>
      <LineItemDiscount>...</LineItemDiscount>
      <LineItemShipping>...</LineItemShipping>
      <LineItemPayment>...</LineItemPayment>
      <LineItemPaymentDiscount>...</LineItemPaymentDiscount>
    </LineItems>
    <CreationDate>13/01/2015 9:42:59 AM</CreationDate>
    <ViewedOn>13/01/2015 9:44:20 AM</ViewedOn>
    <cancelledon/>
    <readyforshippingon>13/01/2015 1:58:41 PM</readyforshippingon>
    <paidon>13/01/2015 9:43:15 AM</paidon>
    <ordercomment>
      removed
    </ordercomment>
  </order>
</export>

I can pull all the elements fine at the first level, however I need to include the tag but it is nested under another level, when I try to get its value like I get the rest of it I get a null value.

        //Create Request
        myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(URL);
        myHttpWebRequest.Method = "GET";
        myHttpWebRequest.ContentType = "text/xml; encoding='utf-8'";

        //Get Response
        myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

        //Load response stream into XMLReader
        myXMLReader = new XmlTextReader(myHttpWebResponse.GetResponseStream());

        var xdoc = XDocument.Load(myXMLReader);

        var result = from x in xdoc.Root.Elements()
                     select new
                     {
                         OrderNumber = (string)x.Element("OrderNumber"),
                         CustomerNumber = (string)x.Element("CustomerNumber"),
                         GrandTotal = (double)x.Element("GrandTotal"),
                         Email = (string)x.Element("Email")
                     };

OUTPUT: "{ OrderNumber = "149612", CustomerNumber = "146538", GrandTotal = 1548.98, Email = null }"

I have never read an XML document before but I'm fairly sure the above code is right, I'm sure I just need to change the LINQ expression line for Email but I don't know what it should be.

Regards

Upvotes: 0

Views: 2949

Answers (2)

Mahesh4b7
Mahesh4b7

Reputation: 66

You can try the easy way. As you already know the XML structure returned by your API,

  1. Create an 'Order' class with similar structure.
  2. Save your XML data to a temporary file.
  3. Use XmlSerializer to Deserialize your XML file and cast it to 'Order' type.
  4. Now you can access all data from object properties.

This link shows exactly how to do that.

Upvotes: 0

Rahul Singh
Rahul Singh

Reputation: 21795

Since Email is present inside Addresses\BillingAddress, You need to extract email like this:-

Email = x.Descendants("BillingAddress")
         .Select(e => (string)e.Element("Email")).FirstOrDefault()

Please note, I am only fetching the Email address present inside BillingAddress node, if you want Email address present inside ShippingAddress node you can do it like this:-

Email = x.Descendants("ShippingAddress")
             .Select(e => (string)e.Element("Email")).FirstOrDefault();

Upvotes: 1

Related Questions