bill
bill

Reputation: 864

How to get all child elements in the parent element of xml in c#

think this is my xml ..

<ListOfDestinations>
  <Destination>
    <City>Ahmedabad</City>
    <Title>Cheap Flights to Ahmedabad</Title>
    <Content>
    <Top10PlacestoVisit>
      <subTitle>1</subTitle>
      <details>d1</details>
      <subTitle>2</subTitle>
      <details>d2</details>
      <subTitle>3</subTitle>
      <details>d3</details>
      <subTitle>4</subTitle>
      <details>d4</details>
      <subTitle>5</subTitle>
      <details>d5</details>
      <subTitle>6</subTitle>
      <details>d6</details>
      <subTitle>7</subTitle>
      <details>d7</details>
      <subTitle>8</subTitle>
      <details>d8</details>
      <subTitle>9</subTitle>
      <details>d9</details>
      <subTitle>10</subTitle>
      <details>d10</details>
    </Top10PlacestoVisit>
    </Content>
   </Destination>
 </ListOfDestinations>

so I want to get all subTitle and details to a list.how can I do that.This is what I tried.

XmlDocument DestinationXml = new XmlDocument();
DestinationXml.Load(Server.MapPath("~/Xml_Data/Destination.xml"));
var xdoc = XDocument.Parse(DestinationXml.InnerXml);


var selectedCity = xdoc.Descendants("ListOfDestinations")
                        .Select(d => d.Elements("Destination")
                        .Where(w => w.Element("City").Value == DesName));

in this place get all the data(subTitle and details) inside the <Top10PlacestoVisit></Top10PlacestoVisit>

then I created a Model and assigned values like this.but I can't get subTitle and details at once to the list.this is what I tried

foreach (var itemz in selectedCity)
{
    var needed = itemz.Elements("Top10PlacestoVisit");
    foreach (var nitems in needed)
   {
       var getSubs = needed.Elements("details");
       foreach (var itm in getSubs)
       {
           details.Add(new Destinations
          {
               details = itm.Value
         });
       }
  }
}

ViewBag.details = details;

in here it successfully gets subTitle but how can I get details and assign it in the same time.help me with this.

Upvotes: 1

Views: 6055

Answers (3)

caldera.sac
caldera.sac

Reputation: 5098

try it like this, add your subTitle as a Attribute inside the details tag like this

<Top10PlacestoVisit>

  <details subTitle ="place01">d1</details>

</Top10PlacestoVisit>

then call it like this.

XElement xe = XElement.Load(Server.MapPath("your path"));

            var check = xe.Descendants("Destination")
                        .Where(n => n.Element("City").Value == "Ahmedabad")
                        .Select(l => l.Element("Top10PlacestoVisit"));

            List<someList> dst = new List<someList>();
          foreach (var item in check)
          {
              var subs = item.Elements("details");
              foreach(var item1 in subs)
              {
                  dst.Add(new someList 
                  {
                      detail = item1.Value,
                      subtitle = item1.Attribute("subTitle").Value

                  });
              }
          }

          ViewBag.all = dst;

Upvotes: 0

Charles Mager
Charles Mager

Reputation: 26223

If you're stuck with your XML, then you can do it by assuming the structure using something like this:

var topPlacesForCity = doc.Descendants("Destination")
    .Where(x => (string) x.Element("City") == "Ahmedabad")
    .Descendants("Top10PlacestoVisit")
    .Elements("subTitle")
    .Select(subTitle => new
    {
        SubTitle = subTitle.Value,
        Details = (string) subTitle.ElementsAfterSelf("details").First()
    });

If, as you mention in the comments, you can change this to incorporate a parent Place element, then it's a little more robust and obvious:

var topPlacesForCity = doc.Descendants("Destination")
    .Where(x => (string) x.Element("City") == "Ahmedabad")
    .Descendants("Top10PlacestoVisit")
    .Elements("Place")
    .Select(place => new
    {
        SubTitle = (string) place.Element("subTitle"),
        Details = (string) place.Element("details")
    });

As an aside, there is no reason to load your XML into XmlDocument to then just parse it straight into XDocument and throw it away. Use XDocument.Load(Server.MapPath("...")) instead.

Upvotes: 1

Andrey Korneyev
Andrey Korneyev

Reputation: 26886

Your xml looks not quite good structured. From my point of view it would be reasonable to put subTitle and details related to it into some enclosing parent element something like:

<Top10PlacestoVisit>
    <Place>
      <subTitle>1</subTitle>
      <details>d1</details>
    </Place>

Anyway, if you're tied up with the structure you've posted and can't change it - you are still able to achieve your goal something like:

var details = xdoc.XPathSelectElements(
       string.Format("/ListOfDestinations/Destination[City='{0}']/Content/Top10PlacestoVisit/details", DesName))
    .Select(d => new { subTitle = (d.PreviousNode as XElement).Value, details = d.Value})
    .ToList();

Notice here using of XPathSelectElements in such a manner to get collection of details is my personal preference, you can do it anyway you like. Key idea here is:

.Select(d => new { subTitle = (d.PreviousNode as XElement).Value, details = d.Value})

on the collection of details elements. So you're just accessing previous sibling element using PreviousNode property of XElement and for each details element it is exactly its related subTitle.

Upvotes: 1

Related Questions