2013-01-26 8 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(); 
    } 

Utilizzando il codice sopra è possibile ottenere il risultato di seguito. enter image description herecome ottenere il valore dell'attributo usando linq su xml?

ma ho bisogno della colonna (WorkPhone) valore 424-555-0545 invece di casa e la colonna (HomePhone) valore 423-555-0124 invece di casa . Cosa dovrei fare per quello?

risposta

11

utilizzare il metodo Where:

Per la casa Numero di telefono:

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

Per la Lavoro numero di telefono:

emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Work").Value 
  • emp.Elements("Phone") è un enumer in grado su tutti gli elementi "Telefono" di emp.
  • Single otterrà l'elemento che soddisfa la proprietà specificata (se sono presenti 0 o più di 1 elemento che soddisfa la proprietà, viene generato un errore).
  • phoneElement.Attribute("Type").Value è il valore dell'attributo "Tipo" (cioè "Casa" o "Lavoro")

Poi, il codice dovrebbe essere:

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, 
       }; 

Se l'elemento emp potrebbe non avere Lavoro telefono o Numero di telefono di casa, il codice di cui sopra genererà un'eccezione nel Single. Per far fronte a questo caso è necessario modificare il codice per:

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

SingleOrDefault sarà pari null se nessun elemento "Telefono" soddisfare la condizione e il string getto su un XElement equivale a XElement.Value.

2

Questo codice funziona anche se v'è esistano Phone elementi per dipendente:

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")        
    }; 

elementi Usa casting per string, int, ecc invece di accedere Value proprietà. Perché? Perché se c'è qualche elemento o attributo mancante nel tuo xml, allora avrai un NullReferenceException. Ma la trasmissione restituirà invece il valore predefinito. Quindi, il codice sopra analizzerà anche xml come questo:

<Employees> 
    <Employee> 
    <EmpId>1</EmpId> 
    <Name>Sam</Name> 
    <Phone Type="Home">423-555-0124</Phone> 
    <Phone>524-777-1234</Phone> 
    </Employee> 
</Employees> 
Problemi correlati