2012-05-30 2 views
0

J'ai un document XML qui va comme ceci:Comment puis-je obtenir tous les sous-nœuds d'un nœud avec certains attributs?

<Menu> 
    <Category name="Comida Rapida"> 
     <Food cocina="si"> 
      <Name>Haburguesa</Name> 
      <Price>10</Price> 
     </Food> 
     <Food> 
      <Name>Papas Fritas</Name> 
      <Price>20</Price> 
     </Food> 
    </Category> 
    <Category name="Bebidas"> 
     <Food> 
      <Name>Pepsi</Name> 
      <Price>30</Price> 
     </Food> 
     <Food cocina="si"> 
      <Name>Coca Cola</Name> 
      <Price>40</Price> 
     </Food> 
    </Category> 
</Menu> 

Ce que je veux faire est de passer par chaque <Category> vérifier si l'attribut est ce que je dois, par exemple « Bebidas », donc la partie que je suis intéressé est:

<Food> 
    <Name>Pepsi</Name> 
    <Price>30</Price> 
</Food> 
<Food cocina="si"> 
    <Name>Coca Cola</Name> 
    <Price>40</Price> 
</Food> 

maintenant que je ce que je veux faire quelque chose de semblable à ce que je l'ai déjà fait:

Je veux d'abord imprimer tous:

Pepsi 30 
Coca Cola 40 

Et je veux imprimer seulement ceux que la nourriture avait l'attribut cocina="si", donc:

Coca Cola 40 

J'ai donc diverses questions:

d'abord tout ce qui approche à utiliser, je Je suis confus par l'abondance des méthodes et des implémentations possibles: XmlDocument, XmlReader, XmlTextReader, etc

De this question Je rassemble XmlDocument est le plus facile à utiliser, ce serait génial, le plus simple, e mieux que je suis tout à fait nouveau à l'analyse des fichiers Xml que vous pouvez apprécier.

Maintenant à la mise en œuvre réelle, j'ai essayé toutes sortes de choses avec pas beaucoup de succès, je semble être en mesure de faire certaines parties, mais pas tous ensemble.

XmlNodeList elemList = doc.GetElementsByTagName("Category"); 
for (int i = 0; i < elemList.Count; i++) 
{ 
    Console.WriteLine(elemList[i].InnerXml); 
} 

Affichera:

<Food><Name>Haburguesa</Name><Price>10</Price></Food><Food><Name>Papas Fritas</Name><Price>20</Price></Food> 
<Food><Name>Pepsi</Name><Price>30</Price></Food><Food><Name>Coca Cola</Name><Price>40</Price></Food> 

Ce qui est logique, mais maintenant, comment puis-je vérifier si la catégorie a l'attribut name="cocina"?

Je devine que quelque chose comme cela pourrait aider:

for (int j = 0; j < elemList[i].Attributes.Count; j++) 
{ 
    //??     
} 

Mais je ne peux pas trouver quelque chose comme MoveToAttribute() dans XmlTextReader.

Et puis encore, comment puis-je vérifier si l'attribut cocina="si"?

Répondre

2

Je pense que LINQ to XML serait la méthode la plus simple ici:

Vous devez utiliser XDocument classe ici. Créez votre objet de document en utilisant les méthodes statiques XDocument.Parse(DOCUMENT) - pour charger un document à partir d'une chaîne - ou XDocument.Load(PATH) - pour charger un document à partir d'un fichier avec un chemin donné.

Après cela, vous pouvez facilement trouver ce que vous cherchez par une requête comme:

var doc = XDocument.Parse("<Menu> ... </Menu>"); 
var results = doc.Descendants("Category") 
       .Where(cat => (string)cat.Attribute("name") == "Bebidas") 
       .SelectMany(cat => cat.Elements("Food")) 
       .Where(food => (string)food.Attribute("cocina") == "si") 
       .Select(food => string.Format("{0} {1}", food.Element("Name"), food.Element("Price"))).ToList(); 

Pour le rendre plus clair, je vais essayer de décrire ce que fait la requête:

  1. Prend tous les éléments nommés "Catégorie" qui sont des descendants de l'élément racine du document
  2. Sélectionne uniquement les catégories, quel attribut "nom" a la valeur "Bebidas"
  3. Projets éléments « alimentaires » au sein de cette catégorie dans une collection
  4. choisit « nourriture » éléments avec « cocina » valeur d'attribut égale à « si »
  5. projets entraînent des éléments dans une chaîne formatée « nom - prix »
+0

Merci, j'essaie! – Trufa

+0

J'ai pris la liberté et changé le format pour Format. – Trufa

+0

J'ai une question cependant, je ne sais pas comment utiliser 'results'. Ne devrait pas un simple pour chaque faire? Aussi, si je lis d'un fichier, je devrais utiliser XDocument.Load() non? – Trufa

1

Vous devez utiliser XPATH au lieu d'écrire du code pour récupérer ces nœuds.

L'expression XPath que vous voulez est "// alimentaire [@cocina = 'si']"

IE utilise doc.selectNodes (XPath) comme moyen d'utiliser XPath, bons navigateurs utilisent doc.evaluate() .

Jetez un oeil ici: http://www.w3schools.com/xpath/xpath_examples.asp

+0

Je vais jeter un coup d'oeil, merci. – Trufa

2

LINQ to XML est bien, mais peut être salissant rapidement. Si vous utilisez XML, vous devez savoir utiliser XPaths pour filtrer les nœuds dont vous avez besoin.

Essayez ceci:

foreach (XmlNode node in doc.SelectNodes("//Food[@cocina = 'si']")) 
{ 
    Console.WriteLine(node.SelectSingleNode("Name").InnerText 
     + " " 
     + node.SelectSingleNode("Price").InnerText); 
} 

XPath sont pris en charge partout; LINQ to XML n'est pas bon pour vous en dehors de .NET.

Questions connexes