【问题标题】:parse an xml for a particular element value解析特定元素值的 xml
【发布时间】:2014-03-17 08:18:53
【问题描述】:

我有一个类似的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 完成吗?怎么样?

【问题讨论】:

  • 旁注 - 您有 station 元素未在此处关闭。 stations 也没有关闭。此外,开始标签 Train 与结束标签 train 不匹配。错误太多。请发布有效的 xml
  • @SergeyBerezovskiy: 抱歉.. 我现在已经编辑了.. 我不能在这里发布实际的 xml,因为它比这更详细,所以只是发布了一个示例结构,只是为了简单地解释我的问题.

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


【解决方案1】:

如果您正在寻找 XPath 和 Linq to 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>

如果某些名称不匹配,请适当更新查询。

【讨论】:

  • 感谢您的回答我已经放置了丢失的括号,但我收到错误@var train = xdoc.XPathSelectElement("//Train[@number='1']");有一些无效的参数..
  • @Vipasha 确保您已引用 System.Xml.LinqSystem.Xml.XPath 命名空间
  • @Vipasha 我刚刚验证了查询 - 它工作正常。确保您的代码与我的代码没有什么不同。注意 - 由于示例 xml 中的元素名称更改,我更新了查询
  • 感谢您提出的所有解决方案。我更喜欢没有 XPath 的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
相关资源
最近更新 更多