monsey11
monsey11

Reputation: 243

C# XML find first Element descendants

Looking to find categoryId and categoryName for first item. It could also return no products.

XML Looks like this

<findItemsByKeywordsResponse xmlns="http://...">
   <ack>Success</ack>
   <version>1.13.0</version>
   <timestamp>2016-11-10T17:48:21.321Z</timestamp>
   <searchResult count="1">
      <item>
        <itemId>12354</itemId>
        <title>ABCD#</title>
        <globalId>ddd</globalId>
        <primaryCategory>
          <categoryId>**1234**</categoryId>
          <categoryName>**Catg Nameee**</categoryName>
        </primaryCategory>
      </item>
   </searchResult>
   <paginationOutput>
   </paginationOutput>
</findItemsByKeywordsResponse>   

Full xml here

Upvotes: 3

Views: 2502

Answers (1)

Gilad Green
Gilad Green

Reputation: 37299

Because your root element has a namespace defined what you should do when searching for the descendant items is specify the namespace:

XNamespace ns = @"http://www.ebay.com/marketplace/search/v1/services";
var result = XDocument.Load("data.xml")
          .Descendants(ns + "item")
          .FirstOrDefault()?.Element(ns + "primaryCategory");

var categoryId = result?.Element(ns + "categoryId")?.Value;
var categoryName = result?.Element(ns + "categoryName")?.Value;

Also you can use C# 6.0 Null Propagation (?:) to retrieve the <primaryCategory> in a more elegant way. Keep in mind that if you do not have an <item> tag or a <primaryCategory> tag the result will be equal to null

In addition it might make more sense to try and find the first <item> that answers some predicate. If that is the case change the .FirstOrDefault() with: .FirstOrDefault(item => item.Element("itemId").Value == "12345") for example

Upvotes: 2

Related Questions