2012-04-10 23 views
6

mio file XML:selezionare XML nodo utilizzando LINQ to XML

<?xml version="1.0" encoding="utf-8"?> 
<ArrayOfCustomer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Customer> 
     <CustomerId>1f323c97-2015-4a3d-9956-a93115c272ea</CustomerId> 
     <FirstName>Aria</FirstName> 
     <LastName>Stark</LastName> 
     <DOB>1999-01-01T00:00:00</DOB> 
    </Customer> 
    <Customer> 
     <CustomerId>c9c326c2-1e27-440b-9b25-c79b1d9c80ed</CustomerId> 
     <FirstName>John</FirstName> 
     <LastName>Snow</LastName> 
     <DOB>1983-01-01T00:00:00</DOB> 
    </Customer> 
</ArrayOfCustomer> 

mio tentativo:

XElement toEdit = 
    (XElement)doc.Descendants("ArrayOfCustomer") 
       .Descendants("Customer") 
       .Where(x => Guid.Parse((x.Descendants("CustomerId") as XElement).Value) == customer.CustomerId) 
       .First<XElement>(); 

questo genera la seguente eccezione:

Object reference not set to an instance of an object. 

1) non è x un XElement?

2) questo è corretto quando lambda per selezionare un nodo Xml?

3) e, naturalmente, come si troverà questo nodo in base a CustomerId?

+0

ho preso l'eccezione: Impossibile eseguire il cast oggetto di tipo 'WhereEnumerableIterator'1 [Sistema .Xml.Linq.XElement] 'per digitare' System.Xml.Linq.XElement '. questo perché ho provato a trasmettere da IEnumrable a un singolo XElement, ho aggiunto una prima estensione () ad esso. ora non riesce a distinguere x come XElement. –

risposta

4

tuo problema è che Descendents e Where restituire un non IEnumerable<XElement> un singolo XElement che è ciò che stai cercando. È possibile risolvere questo come questo:

XElement toEdit = doc.Descendants("ArrayOfCustomer") 
        .Descendants("Customer") 
        .Where(x => Guid.Parse(x.Descendants("CustomerId").Single().Value) == customer.CustomerId) 
        .FirstOrDefault(); 
+0

Basta essere consapevoli che ciò richiede che ci sia un solo elemento CustomerId sotto un Cliente. Se c'è 0 o> 1 genererà un'eccezione. E dopo aver visto il suo XML è probabilmente appropriato. Ma solo qualcosa da sottolineare. –

+0

@AndrewFinnell mentre eravamo sull'argomento, come andresti a modificare quel nodo, ora posso aggiornare tutti i decedenti del Cliente (XElement) ma come aggiornare il nodo nel file? –

2

Non stai trasmettendo x stai trasmettendo x.Descendants(). x.Descendants() restituisce una raccolta, quindi il metodo plurale semantico. Fuori della parte superiore della mia testa si dovrebbe essere in grado di fare x.Descendants("CustomerId").FirstOrDefault() as XElement

1
XElement toEdit = (from c in doc.Descendants("Customer") 
    where Guid.Parse(c.Value) == customer.CustomerId 
    select c).SingleOrDefault(); 
1

avrei ristrutturare la vostra richiesta in questo modo:

XElement toEdit = doc.Descendants("Customer") 
         .Where(x => (Guid)x.Element("CustomerId") == customer.CustomerId) 
         .FirstOrDefault();