2009-10-20 7 views
1

Je souhaite trouver une section de xml basée sur un critère, donc j'utilise linq to XML. Malheureusement, le résultat est toujours nul alors je suppose que j'ai fait quelque chose de mal. L'illustration ci-dessous est un exemple du XML que je suis en train d'analyser.Recherche d'un élément XML spécifique basé sur un ID à l'aide de Linq

<Stuff> 
<ItemsA /> 
<ItemsB /> 
<ItemsC> 
    <Item xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Stuff"> 
    <Id>4bd7b5ac-cb29-4d34-97be-deaebe4a5186</Id> 
    <Children> 
    <Item> 
     <Id>22e3ef6b-4321-40c3-9237-196ba527e9ad </Id> 
     <Name>SomeName</Name> 
    </Item> 
    </Children> 
    <Description>SomeText</Description> 
    <Name>NewName</Name> 
</Item>  

Je regarde la section « ItemsC » où il peut y avoir plusieurs « Item » blocs de XML (un seul est représenté dans cet exemple). Je veux récupérer l'élément basé sur son "Id", celui avec un Id de "4bd7b5ac-cb29-4d34-97be-deaebe4a5186" dans l'exemple ci-dessus.

Le code j'ai utilisé est illustré ci-dessous:

données XElement = XElement.Parse (GetFile());

var pbp = (from b in data.Descendants("Item") 
      where b.Element("Id").Value == "4bd7b5ac-cb29-4d34-97be-deaebe4a5186" 
      select b.Element("Id").Parent).FirstOrDefault(); 

pbp renvoie toujours la valeur null. Quelqu'un peut-il m'aider à produire l'expression linq correcte.

Répondre

0

Eh oui - vous manque juste l'espace de noms:

string desiredId = "4bd7b5ac-cb29-4d34-97be-deaebe4a5186"; 
XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff"; 
var pbp = (from b in data.Descendants(ns + "Item") 
      where b.Element(ns + "Id").Value == desiredId 
      select b).FirstOrDefault(); 

Notez que j'ai simplifié le b.Element("Id").Parent juste b - si vous allez juste en bas de l'arbre puis à nouveau, vous pourriez aussi bien rester où vous êtes :)

Cela suggère une nouvelle simplification à utiliser la notation de points:

string desiredId = "4bd7b5ac-cb29-4d34-97be-deaebe4a5186"; 
XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff"; 
var pbp = data.Descendants(ns + "Item") 
       .Where(b => b.Element(ns + "Id").Value == desiredId) 
       .FirstOrDefault(); 

S'il y a une chance que l'élément ne VHA e un élément "Id", vous pouvez lancer une chaîne à la place:

string desiredId = "4bd7b5ac-cb29-4d34-97be-deaebe4a5186"; 
XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff"; 
var pbp = data.Descendants(ns + "Item") 
       .Where(b => (string) b.Element(ns + "Id") == desiredId) 
       .FirstOrDefault(); 

Cela évite une possible NullReferenceException.

+0

Merci, ce changement fonctionne maintenant. Il est temps pour moi de faire un peu plus de lecture sur Linq :) – Retrocoder

0

Vous avez juste besoin d'ajouter l'espace de noms à la requête, à savoir

XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff"; 

var pbp = 
    (from b in data.Descendants(ns + "Item") 
    where b.Element(ns + "Id").Value == "4bd7b5ac-cb29-4d34-97be-deaebe4a5186" 
    select b.Element(ns + "Id").Parent).FirstOrDefault(); 
Questions connexes