2009-08-24 8 views
0

Je suis en train d'apprendre Linq, et je reste sur ce que j'espère être assez simple. Mon document XML est comme:Lire une valeur d'élément spécifique basée sur un attribut spécifique dans Linq?

<?xml version="1.0" encoding="utf-8"?> 
<XDOC> 
    ... 
    <ItemsDetail> 
     <Item name="Item1"> 
      <data1> 
       <Data type="classA">55</Data> 
       <Data type="classB">66</Data> 
      </data1> 
      <data2> 
       <Data type="classA">77</Data> 
       <Data type="classB">88</Data> 
      </data2> 
     </Item> 
    </ItemsDetail> 
</XDOC> 

Je charge mon XML ci-dessus dans un type XDocument puis la requête

var query = from p in ILSXml.Elements("XDOC").Elements("ItemsDetail").Elements("Item") 
      select p; 

Puis je dirige une foreach sur de la requête.

foreach (var record in query) 
{ 
    Console.WriteLine("Name: {0}", record.Attribute("Name").Value); 
    Console.WriteLine("Data1 ClassA: {0}", record.Element("data1").Element("Data").Attribute("classA").Value); 
} 

Ainsi, la ligne:

Console.WriteLine("Data1 ClassA: {0}", record.Element("data1").Element("Data").Attribute("classA").Value); 

ne fonctionne pas qui, est ce que j'étais assez bien attendre. Dois-je exécuter une autre série de requêtes ou exécuter des méthodes anonymes en ligne? Oh et s'il vous plaît ne pas commenter sur le xml, ce n'est pas le mien, je dois juste travailler avec elle.

Répondre

2

Je suppose que vous essayez d'obtenir la valeur 55? Vous pouvez utiliser la méthode First pour trouver le premier élément "Data" avec une valeur d'attribut "type" de "classA".

record.Element("data1") 
     .Elements("Data") 
     .First(data => data.Attribute("type").Value == "classA") 
     .Value 

Notez que la solution ci-dessus est assez fragile. Toute modification de la structure du document xml d'entrée est susceptible de provoquer une exception de référence nulle.

Vous pouvez également interroger des documents XML à l'aide du langage de requête XPath, plus compact. XPath a la capacité de filtrer les éléments en utilisant une expression simple encapsulée entre crochets. Votre code ressemblerait à ceci:

foreach (var record in ILSXml.XPathSelectElements("XDOC/ItemsDetail/Item")) 
{ 
    Console.WriteLine("Name: {0}", 
     record.Attribute("name").Value); 
    Console.WriteLine("Data1 ClassA: {0}", 
     record.XPathSelectElement("data1/Data[@type='classA']").Value); 
} 
+0

Cela fonctionne, semblable à ce que je regardais tout à l'heure, mais manquant le .First. Existe-t-il un moyen plus recommandé de travailler avec un tel document XML? –

+0

Si vous pouvez mettre la main sur un XSD (document de schéma XML) qui décrit votre document, alors je chercherais certainement à générer de vraies classes et à utiliser la sérialisation XML standard. –

Questions connexes