【问题标题】:How to query XML based on element value如何根据元素值查询 XML
【发布时间】:2015-07-07 01:02:26
【问题描述】:

我有一个IEnumerable<XElement> 对象,我想根据某个节点值进行查询,但不断收到null element 错误。如何根据搜索到的元素的值选择两个元素的值?我正在尝试返回firstNamelastName 其中ID == somevalue

这是我的 XML 的结构:

<Profile>
    <ID>123</ID>
    <firstName>Not</firstName>
    <lastName>Registered</lastName>
</Profile>

我的查询片段:

XDocument xdoc = XDocument.Load(someXml);
IEnumerable<XElement> nodes = xdoc.Root.Elements();
XNamespace ns = "xmlNamespace";

var name = nodes.Elements(ns + "firstName")
     .Where(x => (int)x.Element(ns + "ID") == 123)
     .SingleOrDefault();

我的查询基于this 文章,但我仍然找不到返回我想要的内容的混合物。

更新

我已尝试以下建议的答案,但仍然没有看到任何结果或收到Object reference not set to an instance of an object 异常。

我仍在解决这个问题,现在正在尝试这个:

var result = xdoc
    .Descendants(ns + "Profile")
    .Where(x => (int)x.Element(ns + "ID") == 1)
    .Select(x => new { FirstName = (string)x.Element(ns + "firstName"), LastName = (string)x.Element(ns + "lastName") })
    .FirstOrDefault();

单步执行时,查询在运行Where 子句后挂起。

【问题讨论】:

  • 为什么在这里使用XNamespace,实际的XML有命名空间吗?
  • 还有哪一行正好抛出空引用异常?
  • 您的 Xml 中是否只有一个元素?如果没有,那么根元素是什么,如果有的话。
  • @har07 是的,有一个命名空间&lt;source xmlns='http://www.mysource.com/source'&gt;,然后继续拥有子&lt;Profile&gt; 节点。
  • @user2596756:您知道您可以为您的问题选择答案吗?

标签: c# xml linq linq-to-xml


【解决方案1】:

我想“配置文件”毕竟不是你的 XML 的根。

所以如果我正确地理解了你的想法,你就会有这样的事情:

XML:

<root>
<Profile>
    <ID>123</ID>
    <firstName>Not</firstName>
    <lastName>Registered</lastName>
</Profile>
<Profile>
    <ID>124</ID>
    <firstName>A</firstName>
    <lastName>B</lastName>
</Profile>
</root>

获取 id 元素等于 123 的配置文件部分的代码:

var result = XDocument.Parse(yourXml)
        .Root
        .Elements()
        .SingleOrDefault(i => i.Element("ID").Value == "123");

【讨论】:

  • 执行i.Element("ID").Value == "1" 行时收到Object reference not set to an instance of an object. 异常。请注意,ID = 1 确实存在于我的 XML 架构中。
  • 我发布了完整的工作代码。但是您必须根据您的需要对其进行调整,因为您没有共享您的 xml 架构,并且如果您的 xml 定义了命名空间,请检查来自 hangndv 的答案。
【解决方案2】:

我做这个例子来处理命名空间:

Profiles.xml:

<Profiles xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
    <Profile>
        <ID>122</ID>
        <firstName>Not</firstName>
        <lastName>Registered</lastName>
    </Profile>
    <Profile>   
        <ID>123</ID>
        <firstName>Not</firstName>
        <lastName>Registered</lastName>
    </Profile>
</Profiles>

代码:

XElement xDoc = XElement.Load(@"C:\Profiles.xml");
XNamespace ns = "http://schemas.microsoft.com/2004/06/E2ETraceEvent";

var profile = xDoc.Elements(ns + "Profile")
            .SingleOrDefault(x => x.Element(ns + "ID").Value == "123");
Console.WriteLine("firstName: " + profile.Element(ns + "firstName").Value);
Console.WriteLine("lastName: " + profile.Element(ns + "lastName").Value);

希望对您有所帮助。

【讨论】:

    【解决方案3】:

    你的 xml 像这样

    <?xml version="1.0" encoding="utf-8" ?>
    <Employee>
      <Profile>
        <ID>123</ID>
        <firstName>Kumod</firstName>
        <lastName>Singh</lastName>
      </Profile>
      <Profile>
        <ID>124</ID>
        <firstName>Ravi</firstName>
        <lastName>Ranjam</lastName>
      </Profile>
    </Employee>
    

    我们可以访问名字和姓氏

     string strPath1 = Server.MapPath("~/XmlData/abc.xml");
            var ResultOfFirLasName = (from studentProfile in XDocument.Load(strPath1).Descendants("Profile")
                                      where (int)studentProfile.Element("ID") == 123
                                      select new { FirstName = (string)studentProfile.Element("firstName"), LastName = (string)studentProfile.Element("lastName") }).FirstOrDefault();
            string strFirstName = ResultOfFirLasName.FirstName;
            string LastName = ResultOfFirLasName.LastName;
    

    你也可以使用 lemda 表达式

    var ResultOfFirLasName1 = XDocument.Load(strPath1).Descendants("Profile").Where(x => (int)x.Element("ID") == 123).Select(x=> new {FirstName =(string)x.Element("firstName"),LastName =(string)x.Element("lastName")}).FirstOrDefault();
    

    以同样的方式再次访问名字和姓氏

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多