使用LINQ读取XML文件

8
我有以下XML文件。
<?xml version="1.0" encoding="utf-8"?> 
<Users>
    <User>
        <Name>John Smith</Name>
        <test>
            <Date>23.05.2011</Date>
            <points>33</points>
        </test>
        <test>
            <Date>22.06.2011</Date>
            <points>29</points>
        </test>
    </User>
</Users>

我希望使用LINQ提取用户名为“John Smith”的测试日期和测试得分。

我该如何构建我的LINQ查询?

我已经尝试了以下方法,但效果不如预期:

XElement main = XElement.Load(@"users.xml");

string t = "John Smith";
var v = from user in main.Elements("User")
        where t == users.Element("Name").Value
        select users;

MessageBox.Show(v.First().Element("Date").Value.ToString()); 

1
你的代码不应该编译。你在使用 users 的地方应该使用 user。而且你在 t 的初始化中有一个拼写错误。 - svick
4个回答

7

我不确定您想要的输出格式是什么,但是这个示例代码可以获取日期和点数。将结果投影到匿名类型中:

class Program
{
    static void Main(string[] args)
    {
        XElement main = XElement.Load(@"users.xml");

        var results = main.Descendants("User")
            .Descendants("Name")
            .Where(e => e.Value == "John Smith")
            .Select(e => e.Parent)
            .Descendants("test")
            .Select(e => new { date = e.Descendants("Date").FirstOrDefault().Value, points = e.Descendants("points").FirstOrDefault().Value });

        foreach (var result in results)
            Console.WriteLine("{0}, {1}", result.date, result.points);
        Console.ReadLine();
    }
}

输出结果如下:

23.05.2011, 33
22.06.2011, 29

我该如何在XML文件中插入一个新的“在这个例子中是第三个”<Test>节点,并将日期和积分指向该用户(John Smith)? - brandon

1
尝试一下。
class Program
{
    static void Main(string[] args)
    {
        XElement main = XElement.Parse(
@"<Users>
    <User>
        <Name>John Smith</Name>
        <test>
            <Date>23.05.2011</Date>
            <points>33</points>
        </test>
        <test>
            <Date>22.06.2011</Date>
            <points>29</points>
        </test>
    </User>
</Users>");

        var users =
           from m in main.Elements("User")
           where (string)m.Element("Name") == "John Smith"
           select (m.Descendants("test").Descendants("Date").FirstOrDefault().Value);
        foreach (var user in users)
            Console.WriteLine(user);
        Console.ReadLine();
    }
}

致敬


1
XDocument main = XDocument.Load(@"users.xml"); 

string t = "John Smith"; 
var v = from user in main.Descendants("User") 
    where t == user.Element("Name").Value 
    select user; 

MessageBox.Show(v.First().Element("Date").Value.ToString()); 

应该能解决问题。


0

关于您的另一个问题,即如何向John Smith添加另一个节点,以下是解决方案:

class Program
{
    static void Main(string[] args)
    {
        XElement main = XElement.Parse(
    @"<Users>
       <User>
            <Name>Alex</Name>
            <test>
                <Date>08.05.2011</Date>
                <points>4</points>
            </test>
        </User>
        <User>
            <Name>John Smith</Name>
            <test>
                <Date>23.05.2011</Date>
                <points>33</points>
            </test>
            <test>
                <Date>22.06.2011</Date>
                <points>29</points>
            </test>
        </User>
    </Users>");


    var users =
       from m in main.Elements("User")
       where (string)m.Element("Name") == "John Smith"
       select (m.Descendants("test").Descendants("Date").FirstOrDefault().Value);

    XElement Mercury = main.Elements("User").Where(p => (String)p.Element("Name") == "John Smith").FirstOrDefault();
    Mercury.Add(new XElement("test", new XElement("Date", "06.06.2011"), new XElement("points", "01")));

    foreach (var user in main.Elements())
        Console.WriteLine(user);

    Console.ReadLine();
}

}

给出下一个期望的结果:

<User>
  <Name>Alex</Name>
  <test>
    <Date>08.05.2011</Date>
    <points>4</points>
  </test>
</User>
<User>
  <Name>John Smith</Name>
  <test>
    <Date>23.05.2011</Date>
    <points>33</points>
  </test>
  <test>
    <Date>22.06.2011</Date>
    <points>29</points>
  </test>
  <test>
    <Date>06.06.2011</Date>
    <points>01</points>
  </test>
</User>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接