2013-01-26 42 views
9
<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> 
    </Employee> 
</Employees> 

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 

     emplyeeDetails = XDocument.Load(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName + "\\LinqToXml\\Xmls\\" + "Employees.xml"); 
     var emplyees = from emp in emplyeeDetails.Descendants("Employee").Take(10) 
         orderby emp.Element("EmpId").Value ascending 
         select new 
         { 
          Id = emp.Element("EmpId").Value, 
          Name = emp.Element("Name").Value, 
          Sex = emp.Element("Sex").Value, 
          WorkPhone=emp.Element("Phone").Attribute("Type").Value, 
          HomePhone = emp.Element("Phone").Attribute("Type").Value,        

         }; 
     DgrdEmployeeDetails.ItemsSource = emplyees.ToList(); 
    } 

Sử dụng mã trên tôi có thể nhận được kết quả bên dưới. enter image description herecách lấy Giá trị thuộc tính bằng LINQ to xml?

Nhưng tôi cần cột (WorkPhone) giá trị 424-555-0545 thay vì Home và cột (HomePhone) giá trị 423-555-0124 thay vì Home . Tôi nên làm gì cho điều đó?

Trả lời

11

Sử dụng các phương pháp Where:

Đối với Home số điện thoại:

emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Home").Value 

Đối với làm việc số điện thoại:

emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Work").Value 
  • emp.Elements("Phone") là một enumer có thể trên tất cả các phần tử "Điện thoại" của emp.
  • Single sẽ nhận phần tử thỏa mãn thuộc tính được chỉ định (nếu có 0 hoặc nhiều hơn 1 phần tử thỏa mãn thuộc tính, lỗi được nêu lên).
  • phoneElement.Attribute("Type").Value là giá trị của thuộc tính "Loại" (tức là "Home" hoặc "làm việc")

Sau đó, mã của bạn nên là:

var emplyees = from emp in emplyeeDetails.Descendants("Employee").Take(10) 
       orderby emp.Element("EmpId").Value ascending 
       select new 
       { 
        Id = emp.Element("EmpId").Value, 
        Name = emp.Element("Name").Value, 
        Sex = emp.Element("Sex").Value, 
        WorkPhone = emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Home").Value, 
        HomePhone = emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Work").Value, 
       }; 

Nếu phần tử emp có thể không có Làm việc điện thoại hoặc Trang chủ số điện thoại, mã ở trên sẽ tăng ngoại lệ trong Single. Để đối phó với trường hợp này bạn phải thay đổi mã của bạn để:

(string)emp.Elements("Phone").SingleOrDefault(phoneElement => phoneElement.Attribute("Type").Value == "Home") 

SingleOrDefault sẽ bằng null nếu không có yếu tố "Điện thoại" đáp ứng các điều kiện và string cast trên XElement tương đương với XElement.Value.

2

Mã này sẽ làm việc ngay cả khi có bất kỳ Phone yếu tố tồn tại cho nhân viên:

var emplyees = 
    from emp in emplyeeDetails.Descendants("Employee").Take(10) 
    let phones = emp.Descendants("Phone") 
    orderby (int)emp.Element("EmpId") 
    select new 
    { 
     Id = (int)emp.Element("EmpId"), 
     Name = (string)emp.Element("Name"), 
     Sex = (string)emp.Element("Sex"), 
     WorkPhone = (string)phones.FirstOrDefault(p => (string)p.Attribute("Type") == "Work"), 
     HomePhone = (string)phones.FirstOrDefault(p => (string)p.Attribute("Type") == "Home")        
    }; 

yếu tố sử dụng đúc để string, int, vv thay vì truy cập Value tài sản. Tại sao? Bởi vì nếu có một số yếu tố hoặc thuộc tính bị thiếu trong xml của bạn, thì bạn sẽ nhận được một NullReferenceException. Tuy nhiên, tính năng truyền sẽ trả lại giá trị mặc định thay thế. Vì vậy, mã ở trên sẽ phân tích ngay cả xml như sau:

<Employees> 
    <Employee> 
    <EmpId>1</EmpId> 
    <Name>Sam</Name> 
    <Phone Type="Home">423-555-0124</Phone> 
    <Phone>524-777-1234</Phone> 
    </Employee> 
</Employees> 
Các vấn đề liên quan