3

I need to get the OrderID from these xml data:

<?xml version="1.0" encoding="utf-8"?>
<GetOrdersResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2015-12-10T16:12:55.184Z</Timestamp>
  <Ack>Success</Ack>
  <Version>967</Version>
  <Build>e967_core_Bundled_5642307_R1</Build>
  <OrderArray>
    <Order>
      <OrderID>865826</OrderID>
      <OrderStatus>Active</OrderStatus>
   </Order>
  </OrderArray>
</GetOrdersResponse>

I have tried this one but does not work.

var xDoc = XDocument.Parse(xmlResult);
var orderElements = xDoc.Elements("GetOrdersResponse").Elements("OrderArray").Elements("Order");
foreach (XElement elem in orderElements)
{
    var orderId = Convert.ToInt32(_xmlHelper.GetChildElementValue(elem, "OrderID"));
}

Please advice.

5 Answers 5

3

For such problem, i would always choose using XmlSerializer. Use this classes:

    using System;
    using System.Xml.Serialization;
    using System.Collections.Generic;
    namespace classes
    {
        [XmlType(Namespace = "urn:ebay:apis:eBLBaseComponents")]
   public class Order
    {
        public int OrderID { get; set; }
        public string OrderStatus { get; set; }
    }

    [XmlType(Namespace = "urn:ebay:apis:eBLBaseComponents")]
    public class OrderArray
    {
        public List<Order> Orders { get; set; }
    }

    [XmlRoot(Namespace = "urn:ebay:apis:eBLBaseComponents")]
    public class GetOrdersResponse
    {
        public string Timestamp { get; set; }
        public string Ack { get; set; }
        public string Version { get; set; }
        public string Build { get; set; }
        public OrderArray OrderArray { get; set; }
    }

    }

Then Deserialize to your object:

XmlSerializer serializer = new XmlSerializer(typeof(GetOrdersResponse ));
using (TextReader reader = new StringReader(xmlResult))
{
    GetOrdersResponse result = (GetOrdersResponse) serializer.Deserialize(reader);
}

int id=result.OrderArray.Orders.First().OrderID; //this will return ID of first object in Orders list.
Sign up to request clarification or add additional context in comments.

5 Comments

" [XmlAttribute(AttributeName = "xmlns")] public string Xmlns { get; set; }" looks very very wrong... and most of those should be XmlType, not XmlRoot
fyi it is still far more complex than it needs to be - XmlSerializer makes a lot of reasonable assumptions, such as "namespaces are inherited by children" and "things are elements named like the member" - so all you need is: gist.github.com/mgravell/1b91e0e5e6a47bdb3cff42e61281f6ce - purely FYI
heh, sorry, but I love your answer (I like XmlSerializer), but if we assume that OrderArray is actually 0-1-or-many, you an also lose an entire type (OrderArray) and just use public List<Order> OrderArray { get; set; } on the GetOrdersResponse
Thats right, but one given example it was not necessary. But this should be implemented, otherwise OrderArray would be redundant.
Finally, if you use public int OrderID { get; set; }, the correct conversions will happen automatically
2

You can follow this:

XDocument xdoc = XDocument.Load("YourXMLFile");
var orderId = xdoc.Descendants("OrderID").FirstOrDefault().Value;

Comments

1

I wouldn't expect xDoc.Elements("GetOrdersResponse") to work, because that is looking in the default namespace, where-as everything here is in "urn:ebay:apis:eBLBaseComponents". As such, you'd need at a minimum to tell it that via XName:

    var xDoc = XDocument.Parse(xmlResult);
    XNamespace ns = "urn:ebay:apis:eBLBaseComponents";
    var orderElements = xDoc.Elements(ns + "GetOrdersResponse")
            .Elements(ns + "OrderArray").Elements(ns + "Order");
    foreach (XElement elem in orderElements)
    {
        var orderId = (int)elem.Element(ns + "OrderID");
    }

(note the use of (int) to do xml-specific casting, too)

However, it may be easier to just use XmlSerializer and let it worry about unscrambling the data.

Comments

1

You should be use this sample code

Importent Note

  • Serialized class mark as [Serializable] attirbute
  • If the class name is not same as the xml root tag, class will be mark as [XmlRoot(ElementName = "XmlTagName")] attribute
  • If serialized class have property type as another class, this property mark as [XmlElement("XmlTagName")] attribute

Sample Code

Model

      [Serializable]
        [XmlRoot(ElementName = "HardwareInfo")]
        public class Hardware
        {
            [XmlElement]
            public string cpu_name { get; set; }
            [XmlElement]
            public int ram_size { get; set; }

            [XmlElement("hard_disk")]
            public List<HardDisk> hd { get; set; }                   
        }

        [Serializable]
        [XmlRoot(ElementName = "hard_disk")]
        public class HardDisk
        {
            [XmlElement]
            public string model { get; set; }
            [XmlElement]
            public string size { get; set; }
        }

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xmlString = @"<HardwareInfo>
                                  <cpu_name> ABC Pentium xyz</cpu_name>
                                  <ram_size> 123 </ram_size>
                                  <hard_disk>
                                    <model>Toshiba XYZ</model>
                                    <size> 123 GB </size>
                                  </hard_disk>
                                  <hard_disk>
                                    <model>Logitech XYZ</model>
                                    <size> 99 GB </size>
                                  </hard_disk>
                                </HardwareInfo>";

            var result = DeSerialization<Hardware>(xmlString);
        }

        static T DeSerialization<T>(string xmlStrig) where T : class
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));                        
            using (StringReader sReader = new StringReader(xmlStrig))
            {
                return (T)xmlSerializer.Deserialize(sReader);
            }
        }
    }          
}

1 Comment

sorry, but this is just ... unhelpful; XmlSerializer does not care about [Serializable] - at all. The main complicating factor in the question is namespaces, which this answer doesn't address; and: it isn't even remotely specific to the question...
0

You can get it using XmlDocument and XmlNodeList also - if you are saving the xml data in file

        XmlDocument doc = new XmlDocument();
        doc.Load("your XML File Name with extension");
        XmlNodeList elemList = doc.GetElementsByTagName("OrderID");
        for (int i = 0; i < elemList.Count; i++)
        {
            Console.WriteLine(elemList[i].InnerText);
        }

1 Comment

This will work, but GetElementsByTagName is almost always a terrible solution to any problem - hugely prone to errors etc. The primary complication in the question is namespaces, which can be tackled perfectly fine via the regular query methods of both XDocument and XmlDocument, without needing the nuclear option of GetElementsByTagName

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.