2012-04-10 13 views
6

meine XML-Datei:Wählen Sie XML-Knoten mit 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> 

mein Versuch:

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

dies wirft die folgende Ausnahme:

Object reference not set to an instance of an object. 

1) ist nicht x ein XElement?

2) ist das eine richtige wo Lambda für die Auswahl eines Xml-Knotens?

3) und natürlich wie würden Sie diesen Knoten nach CustomerId finden?

+0

Ich habe zuerst die Ausnahme: Konnte nicht das Objekt des Typs ‚WhereEnumerableIterator'1 [System werfen .Xml.Linq.XElement] ', um' System.Xml.Linq.XElement 'einzugeben. Das war, weil ich versuchte, von IEnumrable zu einem einzelnen XElement zu konvertieren, fügte ich eine erste Erweiterung () hinzu. jetzt kann es einfach x nicht als XElement ausmachen. –

Antwort

4

Ihr Problem zu tun ist, dass Descendents und Where eine IEnumerable<XElement> kein einziges XElement die Rückkehr ist das, was Sie nach. Sie können dies wie folgt beheben:

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

Beachten Sie, dass nur ein CustomerId-Element unter einem Kunden vorhanden sein muss. Wenn 0 oder> 1 ist, wird eine Ausnahme ausgelöst. Und nach dem Betrachten seiner XML ist es wahrscheinlich angemessen. Aber nur etwas, um darauf hinzuweisen. –

+0

@AndrewFinnell, während auf dem Thema waren, wie würden Sie gehen über die Bearbeitung dieses Knotens, ich kann jetzt alle Kunden (XElement) decendents aktualisieren, aber wie würde der Knoten in der Datei aktualisieren? –

2

Sie werfen nicht x Sie sind Casting x.Descendants(). x.Descendants() gibt eine Auflistung zurück, daher die Mehrzahl der Methoden semantisch. Aus der Spitze von meinem Kopf sollten Sie in der Lage sein 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

Ich würde Ihre Abfrage wie folgt neu strukturieren:

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