解析特定元素值的xml

时间:2014-03-17 08:18:54

标签: c# asp.net xml xpath xml-parsing

我有像

这样的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>
}

同样,我有很多列车编号及其详细信息。我想解析特定列车编号的xml并获取与之相关的所有详细信息。 就像我想获得2号火车的详细信息一样。

我使用xpath作为:

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

它不起作用,是什么方法? 这可以通过Linq Xml完成吗?怎么样?

1 个答案:

答案 0 :(得分:3)

如果您正在寻找XPath和Linq到Xml:

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

您在XPath查询中缺少结束括号。如果有任何列车与xml中的号码匹配,那么该查询将为您提供trainData XElement。进一步解析很简单:

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();
}

您也可以在没有XPath的情况下使用纯Linq查询。以下查询将返回第一个匹配的匿名列车对象(如果有)及其编号,条目ID和站点:

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();

注意 - 因此你的样本xml无效(见问题评论)我假设你有以下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>

如果某些名称不匹配,请相应地更新查询。