使用LINQ读取XML节点

3
我在使用LINQ读取XML文件时遇到了问题。
这是我的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<Employees>
  <Employee>
    <Name Type="First">Jack</Name>
    <Name Type="Last">Black</Name>
  </Employee>
  <Employee>
    <Name Type="First">John</Name>
    <Name Type="Last">Blue</Name>
  </Employee>
  <Employee>
    <Name Type="First">Dan</Name>
    <Name Type="Last">Red</Name>
  </Employee>
  <Employee>
    <Name Type="First">Patrick</Name>
    <Name Type="Last">Green</Name>
  </Employee>
</Employees>

我正在使用的代码如下:
    XElement doc = XElement.Load("xmldoc.xml");
    var query = from x in doc.Elements("Employee") where x.Element("Name").Attribute("Type").Value == "First" select x;
    foreach (XElement item in query)
    {
        Console.WriteLine(item.Element("Name").Value);
    }

这段代码返回给我所有的名字,但是当我将属性值从 "first" 改为 "last" 时,它就变成空白了。
当我切换姓名节点时,它会返回姓氏。对我来说,似乎每个雇员查询都返回第一个名称节点的值,忽略第二个节点。你能帮我修复一下吗?

你真的想在查询结果中包含“Employee”元素,还是只需要名字?如果你只需要名字,那么你需要从名字中选择,而不是从员工中选择。否则,你将需要转换结果(例如XPath)以过滤掉你不想要的标签。或者你可以完全省略where,并在你的foreach中获取你想要的标签:Console.WriteLine(item.Elements("Name").Single (i => i.Attribute("Type").Value == "Last").Value); - mellamokb
1个回答

5
问题在于x.Element("Name")调用将返回第一个Name元素。实际上,您需要查询所有Name元素并过滤出具有Last属性值的那个。
请尝试使用以下代码:
var query = from x in doc.Elements("Employee").Elements("Name")
            where x.Attribute("Type").Value == "Last"
            select x;

foreach (XElement item in query)
{
    Console.WriteLine(item.Value);
}

运行得很顺利,但有一个小问题。 只有当我使用XDocument打开XML文件时,你的代码才能正常工作,而不能使用XElement。 - user2847238
@user2847238 对的,我使用了一个 XDocument,所以我添加了 Root 属性。我意识到你使用了一个 XElement,所以它不是必需的。我更新了帖子,现在应该没问题了。 - Ahmad Mageed

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