【问题标题】:LINQ to Xml list wrong queryLINQ to Xml 列出错误查询
【发布时间】:2014-07-07 20:51:31
【问题描述】:

我想用 LINQ 从 xml 文件中获取一些数据,但我不明白。 这是xml文件:

<Data>
  <Customer>
    <Name>bla1</Name>
      <d1>
        <IP>888.888.888.888</IP>
        <UserLogin>userxy</UserLogin>
        <UserPw>pwxy</UserPw>
      </d1>
      <d2>
        <IP>889.889.889.889</IP>
        <UserLogin>userzp</UserLogin>
        <UserPw>pwzp</UserPw>
      </d2>
  </Customer>
</Data>

我想得到例如特定客户的所有 IP 到 List&lt;string&gt;,但我的问题是处理不同的元素 d1d2...dn。因为程序在运行时不知道确切的名称。 显然我的尝试是错误的..

XDocument root = XDocument.Load(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Xml.xml");

List<string> IP = new List<string>();

IP = root.Descendants("Customer").Descendants("Name")
    .Where(x => x.Element("Name").Value == name)
    .Select(x => x.Element("Name").Descendants("IP").ToList<string>();

【问题讨论】:

  • 我认为这是一个 XY 问题 - 您不应该将数据存储在并行集合中。创建一个具有 3 个属性的类:IPUserLoginUserPw,并将其存储在该类实例的列表中。在此处阅读更多信息:msmvps.com/blogs/jon_skeet/archive/2014/06/03/…
  • 您好,感谢您的回答!但老实说,我不明白,如何以这种方式解决它。问题仍然是 LINQ 部分。或者我必须重新组织xml文件吗? :confuse: 什么是“XY”问题?
  • 真丢脸,我用谷歌搜索了“c# xy 问题”。谢谢:D

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


【解决方案1】:

我想得到例如特定客户的所有 IP 到列表中

我猜你正在寻找这样的东西(使用 Linq2Xml 和 Xpath)

var xDoc = XDocument.Parse(xmlstring); // XDocument.Load(filename)

string custName = "bla1";

var ips = xDoc.XPathSelectElement("//Customer[Name[text()='" + custName  + "']]")
            .Descendants("IP")
            .Select(x => (string)x)
            .ToList();

编辑

让我们使用纯 Linq 让 @Bobson 快乐

var ips = xDoc.Descendants("Customer")
        .FirstOrDefault(c=>c.Elements("Name").Any(e=>(string)e==custName))
        .Descendants("IP")
        .Select(x => (string)x)
        .ToList();

【讨论】:

  • 您好,谢谢您的回答。它应该如何工作。谢谢!不知道 XPath... 的东西。明天会看这个:)
  • @Sylverblade - XPath 很丑陋,LINQ-to-SQL 旨在帮助避免它,但有时它只是让事情变得更容易。
  • 嘿,我当然愿意接受其他可以帮助我的建议或提示 :)
  • @Bobson LINQ-to-SQL?这个 SQL/数据库在哪里?如果您的意思是 Linq2ObjectLinq2Xml,您认为答案使用的是什么?
  • @EZI - 你是对的。我习惯于输入 SQL——我的意思是 Linq2Xml。这是漫长的一天。感谢您回答我对 XPaths 的非理性偏见。
【解决方案2】:

这是一个基于 LINQ 查询语法的解决方案:

string customerName = "bla1";

XElement dataElem = XElement.Parse(dataXml);

var ipAddresses =
    from customerElem in dataElem.Elements("Customer")
    where (string)customerElem.Element("Name") == customerName
    from ipElem in customerElem.Descendants("IP")
    select (string)ipElem;

foreach (var ipAddress in ipAddresses)
{
    Console.WriteLine("[{0}]", ipAddress);
}

请参阅下面的完整工作示例,前面是其预期输出。 (另见live demo。)

预期输出:

[888.888.888.888]
[889.889.889.889]

计划:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

namespace LinqQuerySyntaxDemo
{
    public class Program
    {
        static public void Main(string[] args)
        {
            string customerName = "bla1";

            XElement dataElem = XElement.Parse(GetXml());

            var ipAddresses =
                from customerElem in dataElem.Elements("Customer")
                where (string)customerElem.Element("Name") == customerName
                from ipElem in customerElem.Descendants("IP")
                select (string)ipElem;

            foreach (var ipAddress in ipAddresses)
            {
                Console.WriteLine("[{0}]", ipAddress);
            }
        }

        static string GetXml()
        {
            return
               @"<Data>
                   <Customer>
                     <Name>bla1</Name>
                       <d1>
                         <IP>888.888.888.888</IP>
                         <UserLogin>userxy</UserLogin>
                         <UserPw>pwxy</UserPw>
                       </d1>
                       <d2>
                         <IP>889.889.889.889</IP>
                         <UserLogin>userzp</UserLogin>
                         <UserPw>pwzp</UserPw>
                       </d2>
                   </Customer>
                 </Data>";
        }
    }
}

【讨论】:

    【解决方案3】:

    试试这个对我有用

    var xml = XDocument.Load("IPs.xml");
                var Ips = from ip in xml.Descendants("IP")
                          select ip.Value;
    

    从上面的代码

    • 第 1 行将帮助您使用 XDocument.Load 方法加载 xml, IPs.xml 是 xml 文件的名称

      • .一旦你用第二行代码加载了 xml,你将拥有 Ips 作为包含内部文本的字符串列表 xml 中的元素 IP

    【讨论】:

    • 您能否扩展您的答案,详细说明您正在做什么以及它如何帮助解决手头的问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多