C# 4.0 使用linq to xml在类似命名元素的属性上过滤xml文件

C# 4.0 使用linq to xml在类似命名元素的属性上过滤xml文件,c#-4.0,attributes,linq-to-xml,C# 4.0,Attributes,Linq To Xml,我想解决方法很简单,但尽管我在互联网上进行了广泛的搜索,却没有找到答案。请帮忙!问题是:如果所需属性不在同名元素的第一个元素内,则我的xml查询不会返回所需结果。例如,此代码不返回任何内容: XElement xelement = XElement.Load("~/Employees.xml")); var homePhone = from phoneno in xelement.Elements("Employee") where (string)

我想解决方法很简单,但尽管我在互联网上进行了广泛的搜索,却没有找到答案。请帮忙!问题是:如果所需属性不在同名元素的第一个元素内,则我的xml查询不会返回所需结果。例如,此代码不返回任何内容:

XElement xelement = XElement.Load("~/Employees.xml"));
        var homePhone = from phoneno in xelement.Elements("Employee")
               where (string)phoneno.Element("Phone").Attribute("Type") == "Work"
        select phoneno;
foreach (XElement xEle in homePhone)
        TextBox1.Text= xEle + "/n";
然而,如果我用“家”代替“工作”,我会得到所需的结果。事实上,我应该得到与“工作”完全相同的结果。有人能解释一下怎么做吗

xml模板是:

<?xml version="1.0" encoding="utf-8" ?>
<Employees>
  <Employee>
    <EmpId>1</EmpId>
    <Name>Sam</Name>
    <Sex>Male</Sex>
    <Phone Type="Home">423-555-0124</Phone>
    <Phone Type="Work">424-555-0545</Phone>
    <Address>
      <Street>7A Cox Street</Street>
      <City>Acampo</City>
      <State>CA</State>
      <Zip>95220</Zip>
      <Country>USA</Country>
    </Address>
  </Employee>
  <Employee>
    <EmpId>2</EmpId>
    <Name>Lucy</Name>
    <Sex>Female</Sex>
    <Phone Type="Other">143-555-0763</Phone>
    <Phone Type="Work">434-555-0567</Phone>
    <Address>
      <Street>Jess Bay</Street>
      <City>Alta</City>
      <State>CA</State>
      <Zip>95701</Zip>
      <Country>USA</Country>
    </Address>
  </Employee>
  <Employee>
    <EmpId>3</EmpId>
    <Name>Kate</Name>
    <Sex>Female</Sex>
    <Phone Type="Home">166-555-0231</Phone>
    <Phone Type="Other">233-555-0442</Phone>
    <Address>
      <Street>23 Boxen Street</Street>
      <City>Milford</City>
      <State>CA</State>
      <Zip>96121</Zip>
      <Country>USA</Country>
    </Address>
  </Employee>
  <Employee>
    <EmpId>4</EmpId>
    <Name>Chris</Name>
    <Sex>Male</Sex>
    <Phone Type="Work">564-555-0122</Phone>
    <Phone Type="Other">442-555-0154</Phone>
    <Address>
      <Street>124 Kutbay</Street>
      <City>Montara</City>
      <State>CA</State>
      <Zip>94037</Zip>
      <Country>USA</Country>
    </Address>
  </Employee>
</Employees>

1.
山姆
男性
423-555-0124
424-555-0545
考克斯街7A号
阿坎波
加利福尼亚州
95220
美国
2.
露西
女性
143-555-0763
434-555-0567
杰斯湾
阿尔塔
加利福尼亚州
95701
美国
3.
凯特
女性
166-555-0231
233-555-0442
博克森街23号
米尔福德
加利福尼亚州
96121
美国
4.
克里斯
男性
564-555-0122
442-555-0154
库特贝124
蒙塔拉
加利福尼亚州
94037
美国
此行:

where (string)phoneno.Element("Phone")
确实只使用了第一个Phone元素,因为您只请求了一个。您需要使用
Elements
方法,但您可以迭代所有电话,而不是员工:

from phone in xelement.Descendants("Phone")
where (string)phone.Attribute("Type") == "Work"
select phone;
如果要确保此电话属于员工,请在
中添加此条件,其中

phone.Parent.Name == "Employee"
当有多个元素时,元素(“name”)将返回给定名称的第一个元素。你真的想要这个:

var employeesWithHomePhone = from e in xdocument.Root.Elements("Employee")
                             where e.Elements("Phone").Any( p => (string)p.Attribute("Type") == "Home") 
                             select e;

只需将“Home”改为“Work”就可以得到带有工作编号的元素

IEnumerableSorry中没有元素方法,我的代码有点混乱。对我先前代码的更正。与其说是“selectphoneno.Element(“Phone”);”,不如说是“selectphonono;”,这样我的问题才有意义。你现在能检查一下吗?我不确定你想查询什么,你能用英语而不是源代码解释一下吗?我已经修改了原始模板的属性以使问题更清楚。问题是,“给我员工有“家”电话号码的员工元素”。下一个查询是获取雇员有“工作”电话号码的雇员元素。使用我的查询,我得到了“Home”的员工ID 1和3,这是正确的。但是我的“工作”只有员工id 4,而我应该得到员工id 1、2和4。它很有魅力,全面地回答了这个问题。谢谢,太棒了!你能解释一下“=>”代表什么,或者我可以在哪里进一步研究它吗?这对我来说是一个新符号。谢谢,但是结果并没有给出以“Employee”标记开头的xml树,这正是我需要的,因为我想将它保存为xml文件。如果我查询“Home”属性,我会得到xml树。424-555-0545 434-555-0567 233-555-0442 442-555-0154424-555-0545 434-555-0567 233-555-0442 442-555-0154