1

I am getting raw XML response from eBay API call. Now I have to grab values from XML and add those values to ViewModel object then return data to my View. I have already tried few things bellow but I am unable to grab XML response items and assign to ViewModel. Please check each part of code below and let me know if you have any solution. I don't need working code coz i know you cant test it since its uncompleted. Just simple hints would enough, however, i am new with c#. Thanks a lot in advance

Controller:

public ActionResult Search(string OperationName, string calltype, string page, string keywords, string type, string location, string condition, string min, string max, string negative, string minFeedback, string maxFeedback, string drange, string categoryId)
        {
            string AppId = "KavinHim-BestProd-PRD-785446bf1-666"; //api configs
            string BaseUrl = "http://svcs.ebay.com/services/search/FindingService/v1?OPERATION-NAME="; //base url api end point

            if (calltype == "categoryClick")
            {
                string Url = BaseUrl + OperationName + "&SERVICE-VERSION=1.0.0&SECURITY-APPNAME=" + AppId + "&RESPONSE-DATA-FORMAT=XML&REST-PAYLOAD&categoryId=" + categoryId + "&paginationInput.entriesPerPage=2&paginationInput.pageNumber=" + page + "";
                var client = new RestClient(Url);
                var request = new RestRequest(Method.GET);
                request.Method = Method.GET;
                request.Parameters.Clear();
                var xmlResponse = client.Execute(request).Content;

                XmlDocument xdoc = new XmlDocument();
                xdoc.LoadXml(new WebClient().DownloadString(xmlResponse));


                var items = new List<EbayDataViewModel>();

                foreach (var item in items)
                {
                   //add items from xml data to EbayDataViewModel object

                }

            }
            return View();
        }

ViewModel:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebApplication2.Models;

namespace WebApplication2.ViewModels
{
    public class EbayDataViewModel
    {
        public string EbayImageUrl { get; set; }
        public string EbayTitle { get; set; }
        public string NumberOfSales { get; set; }
        public string NumberOfWatch { get; set; }
    }


}

XML Response:

<?xml version="1.0" encoding="UTF-8"?>

-<findItemsByCategoryResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">

<ack>Success</ack>

<version>1.13.0</version>

<timestamp>2017-10-14T08:27:04.876Z</timestamp>


-<searchResult count="2">


-<item>

<itemId>332390426668</itemId>

<title>حجاب روحاني يتحرك,حجاب الغزال أوالظبي ,أقوى حجاب للمحبة والزواج ,حرز حي يتفاعل </title>

<globalId>EBAY-US</globalId>


-<primaryCategory>

<categoryId>162918</categoryId>

<categoryName>Islamic</categoryName>

</primaryCategory>

<galleryURL>http://thumbs1.ebaystatic.com/m/mf7QDRtgSn83eQF23aLFD_Q/140.jpg</galleryURL>

<viewItemURL>http://www.ebay.com/itm/-/332390426668</viewItemURL>

<paymentMethod>PayPal</paymentMethod>

<autoPay>true</autoPay>

<postalCode>04468</postalCode>

<location>Old Town,ME,USA</location>

<country>US</country>


-<shippingInfo>

<shippingServiceCost currencyId="USD">0.0</shippingServiceCost>

<shippingType>FlatDomesticCalculatedInternational</shippingType>

<shipToLocations>Worldwide</shipToLocations>

<expeditedShipping>false</expeditedShipping>

<oneDayShippingAvailable>false</oneDayShippingAvailable>

<handlingTime>1</handlingTime>

</shippingInfo>


-<sellingStatus>

<currentPrice currencyId="USD">350.0</currentPrice>

<convertedCurrentPrice currencyId="USD">350.0</convertedCurrentPrice>

<sellingState>Active</sellingState>

<timeLeft>P10DT14H19M17S</timeLeft>

</sellingStatus>


-<listingInfo>

<bestOfferEnabled>true</bestOfferEnabled>

<buyItNowAvailable>false</buyItNowAvailable>

<startTime>2017-09-24T22:46:21.000Z</startTime>

<endTime>2017-10-24T22:46:21.000Z</endTime>

<listingType>StoreInventory</listingType>

<gift>false</gift>

<watchCount>6</watchCount>

</listingInfo>

<returnsAccepted>true</returnsAccepted>

<galleryPlusPictureURL>http://galleryplus.ebayimg.com/ws/web/332390426668_1_1_1.jpg</galleryPlusPictureURL>

<isMultiVariationListing>false</isMultiVariationListing>

<topRatedListing>false</topRatedListing>

</item>


-<item>

<itemId>382249935959</itemId>

<title>Circa 900 AD Authentic Viking Bronze Snake Bracelet Found In Latvia Excavation</title>

<globalId>EBAY-US</globalId>


-<primaryCategory>

<categoryId>162920</categoryId>

<categoryName>Viking</categoryName>

</primaryCategory>

<galleryURL>http://thumbs4.ebaystatic.com/m/mf73oCtiHN2GGSZlIY0VP7Q/140.jpg</galleryURL>

<viewItemURL>http://www.ebay.com/itm/Circa-900-AD-Authentic-Viking-Bronze-Snake-Bracelet-Found-Latvia-Excavation-/382249935959</viewItemURL>

<paymentMethod>PayPal</paymentMethod>

<autoPay>true</autoPay>

<postalCode>80932</postalCode>

<location>Colorado Springs,CO,USA</location>

<country>US</country>


-<shippingInfo>

<shippingServiceCost currencyId="USD">0.0</shippingServiceCost>

<shippingType>Free</shippingType>

<shipToLocations>Worldwide</shipToLocations>

<expeditedShipping>false</expeditedShipping>

<oneDayShippingAvailable>false</oneDayShippingAvailable>

<handlingTime>1</handlingTime>

</shippingInfo>


-<sellingStatus>

<currentPrice currencyId="USD">52.0</currentPrice>

<convertedCurrentPrice currencyId="USD">52.0</convertedCurrentPrice>

<sellingState>Active</sellingState>

<timeLeft>P28DT14H3M39S</timeLeft>

</sellingStatus>


-<listingInfo>

<bestOfferEnabled>false</bestOfferEnabled>

<buyItNowAvailable>false</buyItNowAvailable>

<startTime>2017-10-12T22:30:43.000Z</startTime>

<endTime>2017-11-11T22:30:43.000Z</endTime>

<listingType>FixedPrice</listingType>

<gift>false</gift>

<watchCount>1</watchCount>

</listingInfo>

<returnsAccepted>true</returnsAccepted>

<isMultiVariationListing>false</isMultiVariationListing>

<topRatedListing>true</topRatedListing>

</item>

</searchResult>


-<paginationOutput>

<pageNumber>1</pageNumber>

<entriesPerPage>2</entriesPerPage>

<totalPages>27113</totalPages>

<totalEntries>54226</totalEntries>

</paginationOutput>

<itemSearchURL>http://www.ebay.com/sch/37903/i.html?_ddo=1&_ipg=2&_pgn=1</itemSearchURL>

</findItemsByCategoryResponse>
gorkem
  • 731
  • 1
  • 10
  • 17
John Lk
  • 185
  • 2
  • 15
  • You can access values from you `XmlDocument` to populate your model using [XmlDocument.SelectNodes Method](https://msdn.microsoft.com/en-us/library/system.xml.xmldocument.selectnodes(v=vs.110).aspx). You shouldn't have to specify very complex xpath - see [here](https://www.w3schools.com/xml/xpath_examples.asp) for some examples. – Poosh Oct 14 '17 at 09:14

2 Answers2

1

If you're not using .NET Version 3.0 or lower, It's highly recommend to use XDocument over XmlDocument: reference link

Anyway, you can use .Descendants() to get all descendants, and then compare the local name of all its elements to see if there is an element whose local name matches the name of item.

(Tested)

var items = new List<EbayDataViewModel>();

// You can directly plug the url in with .Load() method.
// No need to create HttpClient to download the response as string and then
// parse.
XDocument xdoc = XDocument.Load(url);

// Since you're only interested in <item> collections within <searchResult>
var searchResultItems = xdoc.Descendants()
    .Where(x => x.Name.LocalName == "item");

foreach (var sri in searchResultItems)
{
   // Get all child xml elements
   var childElements = sri.Elements();

   var itemId = childElements.FirstOrDefault(x => x.Name.LocalName == "itemId");
   var title = childElements.FirstOrDefault(x => x.Name.LocalName == "title");

   //add items from xml data to EbayDataViewModel object
    items.Add(new EbayDataViewModel {
        EbayTitle = title == null? Stirng.Empty : title.Value,
        ...
    });
}

return items;

Since there are lots of checking and comparison, writing extention methods for those would be useful.

public static class XElementExtensions
{
    public static XElement LocalNameElement(this XElement parent, string localName)
    {
        return parent.Elements().FirstOrDefault(x => x.Name.LocalName == localName);

    public static IEnumerable<XElement> LocalNameElements(this XElement parent, string localName)
    {
        return parent.Elements().Where(x => x.Name.LocalName == localName);
    }

    public static string LocalNameElementValue(this XElement parent, string localName)
    {
        var element = parent.LocalNameElement(localName);
        return element == null? String.Empty : element.Value;
    }

    ...
}
David Liang
  • 20,385
  • 6
  • 44
  • 70
  • https://ibb.co/hpDPiw check this screen shot. i am getting error : 'Illegal characters in path.' – John Lk Oct 14 '17 at 09:08
  • Can you give me the url so that I can plug it to my Rest client? – David Liang Oct 14 '17 at 09:22
  • // working url: http://svcs.ebay.com/services/search/FindingService/v1?OPERATION-NAME=findItemsByCategory&SERVICE-VERSION=1.0.0&SECURITY-APPNAME=KavinHim-BestProd-PRD-78e3e6bf1-97d9ef25&RESPONSE-DATA-FORMAT=XML&REST-PAYLOAD&categoryId=37903&paginationInput.entriesPerPage=100&paginationInput.pageNumber=4 – John Lk Oct 14 '17 at 09:23
  • any solution? @David Liang – John Lk Oct 14 '17 at 09:49
  • No, you just need to plug your url directly to `XDocument.Load()`. You don't need to create a client and download the response as string. @JohnLk – David Liang Oct 14 '17 at 10:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/156723/discussion-between-david-liang-and-john-lk). – David Liang Oct 14 '17 at 10:11
  • Thanks @David Liang – John Lk Oct 14 '17 at 10:28
0

One way would be accessing the item node values from your XmlDocument using XPath query strings. You'll probably want to loop over the response items and create new ViewModel objects to populate your list of ViewModels:

var items = new List<EbayDataViewModel>();
var responseItems = xdoc.SelectNodes("item");
foreach (responseItem in responseItems)
{
    items.Add(new EbayDataViewModel() 
        { EbayImageUrl = responseItem.SelectSingleNode("galleryURL").InnerText,
          EbayTitle = responseItem.SelectSingleNode("title").InnerText,
          NumberOfSales = responseItem.SelectSingleNode("").InnerText,
          NumberOfWatch = responseItem.SelectSingleNode("").InnerText
        });
}

Note: I couldn't find anything that looked like "NumberOfSales or NumberOfWatch" in the XML Response, so those XPaths will need to be filled in.

See XmlDocument.SelectNodes for documentation on this method.

Poosh
  • 532
  • 2
  • 10
  • 25