1

i have a xml like

{
<TrainTime>
<Train number="1">
<trainData>
<entry id="111"/>
<stations>
<station name="s1" id="s_s1" dep="11:10:00" arr=""/>
<station name="s2" id="s_s2" dep="" arr=""/>
<station name="s3" id="s_s3" dep="" arr=""/>
.
.
.
</stations>
</trainData>
</train>
<Train number="5">
<trainData>
<entry id="222"/>
<stations>
<station name="t1" id="s_t1" dep="" arr=""/>
<station name="t2" id="s_t2" dep="" arr=""/>
<station name="t3" id="s_t3" dep="" arr=""/>
.
.
.
 </stations>
</trainData>
</train>
</TrainTime>
}

Similarly, I have many train Numbers and their details. I want to parse the xml for a particular train number and get all the details related to it. Like if I want to get the details for train number 2.

I am using xpath as:

{xPath = "//Train[@number='1'/trainData/stations";}

Its not working and whats the correct way? Can this also be done through Linq Xml? How?

2
  • Side notes - you have station elements not closed here. Also stations is not closed. Also start tag Train does not match end tag train. Too many errors. Please, post valid xml Commented Mar 17, 2014 at 8:46
  • @SergeyBerezovskiy: sorry.. i have edited it now.. I can't post the actual xml here as it is more detailed than this so just posted a sample structure only to explain my problem in short. Commented Mar 17, 2014 at 8:53

1 Answer 1

3

If you are looking for XPath and Linq to Xml:

var xdoc = XDocument.Load(path_to_xml);
var data = xdoc.XPathSelectElement("//Train[@number='1']/trainData");
                                                       ^

You are missing closing bracket in your XPath query. That query will give you trainData XElement if there is any train matching your number in xml. Further parsing is simple:

if (data != null)
{
    int entryId = (int)data.Element("entry").Attribute("id");
    var stations = data.Element("stations")
                       .Elements("station")
                       .Select(s => new {
                            Name = (string)s.Attribute("name"),
                            Id = (string)s.Attribute("id"),
                            Arrival = (string)s.Attribute("arr"),
                            Departure = (string)s.Attribute("dep")
                       }).ToList();
}

You can also use pure Linq query without XPath. Following query will return first matching anonymous train object (if any) with its number, entry id and stations:

int number = 1; // number of train to find
var train = (from t in xdoc.Root.Elements("Train")
             let d = t.Element("trainData")
             where (int)t.Attribute("number") == number
             select new {
                Number = number,
                EntryId = (int)d.Element("entry").Attribute("id"),
                Stations = (from s in d.Element("stations").Elements("station")
                            select new {
                                 Name = (string)s.Attribute("name"),
                                 Id = (string)s.Attribute("id"),
                                 Arrival = (string)s.Attribute("arr"),
                                 Departure = (string)s.Attribute("dep")
                            }).ToList()
            }).FirstOrDefault();

NOTE - thus your sample xml is not valid (see comment under question) I assumed you have following structure of xml:

<TrainTime>
  <Train number="1">
    <trainData>
      <entry id="111"/>
      <stations>
        <station name="s1" id="s_s1" dep="11:10:00" arr=""/>
        <station name="s2" id="s_s2" dep="" arr=""/>
        <station name="s3" id="s_s3" dep="" arr=""/>
      </stations>
    </trainData>
  </Train>
  <Train number="5">
    <trainData>
      <entry id="222"/>
      <stations>
        <station name="t1" id="s_t1" dep="" arr=""/>
        <station name="t2" id="s_t2" dep="" arr=""/>
        <station name="t3" id="s_t3" dep="" arr=""/>
      </stations>
    </trainData>
  </Train>
</TrainTime>

If some names do not match, update query appropriately.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your answer I have placed the missing bracket but I am getting error @ var train = xdoc.XPathSelectElement("//Train[@number='1']"); has some invalid arguments..
@Vipasha make sure you have referenced System.Xml.Linq and System.Xml.XPath namespaces
@Vipasha I just verified query - it works fine. Make sure your code does not differs from mine. Note - I updated query due to element name changes in your sample xml
thanks all the solutions suggested by you are working..I prefer the one without XPath.

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.