繁体   English   中英

如何使用 LINQ C# 正确搜索 xml 文档

[英]How to properly search xml document using LINQ C#

我很难弄清楚如何正确搜索 xml 文档。 我今天一直在疯狂地阅读其他表格,但似乎无法理解。 希望有人能给我一些关于如何以正确的方式做到这一点以及为什么使用 LINQ 的更详细的信息。 这是 XML 文件。

<?xml version="1.0" encoding="utf-8"?>
<body>
  <Customers>
    <Client>
      <Firstname Value="someguy" />
      <LastName Value="test" />
      <PhoneNumber Value="541555555" />
      <Address Value="55 nowhere" />
      <City Value="sometown" />
      <State Value="somestate" />
    </Client>
  </Customers>
</body>

我要完成的是返回与客户名称匹配的每个元素的所有值。 这是我的代码。

       IEnumerable<XElement> test = doc.Root.Descendants()
            .Where(nodeName => nodeName.Name == "Client"
            && nodeName.Descendants().Any(x => x.Name == "Firstname"
            && x.Value == "someguy"));

        foreach (XElement m in test)
        {
            MessageBox.Show(m.ToString());
        }

非常感谢您的帮助。 如果可能,还请解释使用 LINQ 的想法与格式类似。 不太确定如何解释我的要求,但在大多数情况下只是对它的工作方式或格式等有更多的了解......

编辑

我已经尝试了给出的解决方案,但似乎仍然没有任何效果。 请告诉我我在这里做错了什么。

        private void button2_Click(object sender, EventArgs e)
    {
        string seach = txtSearch.Text;

        XDocument doc = XDocument.Load(@"C:\users\tim\desktop\test.xml");

        var result = doc.Elements("Customers")
            .Elements("Client")
            .Where(x => x.Elements("Firstname")
                         .Where(c => c.Attribute("Value").Value == "someguy")
                         .Any())
            .ToList();

        foreach (var m in result)
        {
            MessageBox.Show(m.ToString());
        }
    }

编辑:

好的,我现在已经开始工作并输出我正在寻找的数据。 有人可以告诉我是否有更有效的方法来执行我在此编辑下方发布的内容。

        private void button2_Click(object sender, EventArgs e)
    {
        string seach = txtSearch.Text;

        XDocument doc = XDocument.Load(@"C:\users\tim\desktop\test.xml");

        var result = (from clientNode in doc.Root.Descendants("Client")
                      from name in clientNode.Descendants("Firstname")
                      where name.Attribute("Value").Value == "someguy"
                      select new
                      {
                          Fname = clientNode.Element("Firstname").Attribute("Value").Value,
                          Lname = clientNode.Element("LastName").Attribute("Value").Value,
                          Phone = clientNode.Element("PhoneNumber").Attribute("Value").Value,
                          Address = clientNode.Element("Address").Attribute("Value").Value,
                          City = clientNode.Element("City").Attribute("Value").Value,
                          State = clientNode.Element("State").Attribute("Value").Value
                      });

        foreach (var m in result)
        {
            MessageBox.Show(m.Fname + "\n" +
                            m.Lname + "\n" +
                            m.Phone + "\n" +
                            m.Address + "\n" +
                            m.City + "\n" +
                            m.State);
        }

您可以使用XElement并使用 LINQ 查询进行搜索,如下所示:

XElement doc = XElement.Parse(xml);
var result = doc.Elements("Customers")
                .Elements("Client")
                .Where(x => x.Elements("Firstname")
                             .Where(c => c.Attribute("Value").Value == "someguy")
                             .Any())
                .ToList();

所以输入:

var xml =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<body>
    <Customers>
    <Client>
        <Firstname Value=""someguy"" />
        <LastName Value=""some last name"" />
        <PhoneNumber Value=""123456"" />
        <Address Value=""some where"" />
        <City Value=""some town"" />
        <State Value=""some state"" />
    </Client>
    <Client>
        <Firstname Value=""someotherguy"" />
        <LastName Value=""some other last name"" />
        <PhoneNumber Value=""123456"" />
        <Address Value=""some other where"" />
        <City Value=""some other town"" />
        <State Value=""some other state"" />
    </Client>
    </Customers>
</body>";

XElement doc = XElement.Parse(xml);
var result = doc.Elements("Customers")
                .Elements("Client")
                .Where(x => x.Elements("Firstname")
                             .Where(c => c.Attribute("Value").Value == "someguy")
                             .Any())
                .ToList();

结果将是:

<Client>
    <Firstname Value=""someguy"" />
    <LastName Value=""some last name"" />
    <PhoneNumber Value=""123456"" />
    <Address Value=""some where"" />
    <City Value=""some town"" />
    <State Value=""some state"" />
</Client>

您可以显示值,例如:

MessageBox.Show(string.Format("Firstname: {0}\nLastName: {1}\nPhoneNumber: {2}\nAddress: {3}\nCity: {4}\nState: {5}",
                result[0].Element("Firstname").Attribute("Value").Value,
                result[0].Element("LastName").Attribute("Value").Value,
                result[0].Element("PhoneNumber").Attribute("Value").Value,
                result[0].Element("Address").Attribute("Value").Value,
                result[0].Element("City").Attribute("Value").Value,
                result[0].Element("State").Attribute("Value").Value));

笔记:

  • 如果您知道结果应该包含 0 或 1 个元素,则可以使用FirstOrDefault()而不是ToList()
  • 元素名称区分大小写,因此请注意Firstname例如。
  • 您可以使用XElement.Load()从文件加载,例如XElement doc = XElement.Load(@"d:\\file.xml");
  • 如果您以这种方式选择元素,则查询将更具容错性.Where(c => c.Name.ToString().ToLower() == "Customers".ToLower())
  • 如果您以这种方式选择属性,则查询将更具容错性.Where(c => c.Attributes("Value").Where(a=>a.Value == "someguy").Any())

作为@Reza Aghaei 解决方案的替代方案, XPath也是一个解决方案

var xml =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<body>
    <Customers>
    <Client>
        <Firstname Value=""someguy"" />
        <LastName Value=""some last name"" />
        <PhoneNumber Value=""123456"" />
        <Address Value=""some where"" />
        <City Value=""some town"" />
        <State Value=""some state"" />
    </Client>
    <Client>
        <Firstname Value=""someotherguy"" />
        <LastName Value=""some other last name"" />
        <PhoneNumber Value=""123456"" />
        <Address Value=""some other where"" />
        <City Value=""some other town"" />
        <State Value=""some other state"" />
    </Client>
    <Client>
        <Firstname Value=""someguy"" />
        <LastName Value=""some other last name"" />
        <PhoneNumber Value=""12345634543"" />
        <Address Value=""some other where"" />
        <City Value=""some other town"" />
        <State Value=""some other state"" />
    </Client>
    </Customers>
</body>";
XElement doc = XElement.Parse(xml);

foreach(var client in doc
 .XPathSelectElements("./Customers/Client/Firstname[@Value='someguy']")
 .Select(x => x.Parent))
    Console.WriteLine (client);

如果您更喜欢Linq To Xml解决方案:

var results = (from c in doc.Descendants("Client")
            from f in c.Descendants("Firstname")
             where (string)f.Attribute("Value") == "someguy"
             select c).ToList();
foreach(var r in results)
    Console.WriteLine (r);

如何:使用复杂过滤将 Linq 写入 Xml 查询

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM