Reputation: 864
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
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
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
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