2010-07-26 4 views
2

Je dispose d'un fichier de mappage XML qui ressemble à ceciLINQ to XML, sélectionnez tous les attributs et leurs valeurs pour un noeud donné

<colourMappings> 
    <model name="modelX"> 
     <mapping colour="White" configCode="1"></mapping> 
     <mapping colour="Aluminium" configCode="2"></mapping> 
     <mapping colour="Black" configCode="3"></mapping> 
     <mapping colour="Blue" configCode="4"></mapping> 
     <mapping colour="White Pearl" configCode="5"></mapping> 
     <mapping colour="Graphite" configCode="6"></mapping> 
     <mapping colour="Gunmetal" configCode="7"></mapping> 
     <mapping colour="Indigo" configCode="8"></mapping> 
     <mapping colour="Red" configCode="9"></mapping> 
    </model> 
    <model name="modelY"> 
     <mapping colour="White" configCode="1" stConfigCode= "xx" dgConfigCode="hj"></mapping> 
     <mapping colour="Aluminium" configCode="2" stConfigCode= "xy" dgConfigCode="gh"></mapping> 
     <mapping colour="Black" configCode="3" stConfigCode= "xt" dgConfigCode="fg"></mapping> 
     <mapping colour="Blue" configCode="4" stConfigCode= "sd" dgConfigCode="fg"></mapping> 
     <mapping colour="White Pearl" configCode="5" stConfigCode= "df" dgConfigCode="df"></mapping> 
     <mapping colour="Graphite" configCode="6" stConfigCode= "xc" dgConfigCode="df"></mapping> 
     <mapping colour="Gunmetal" configCode="7" stConfigCode= "cv" dgConfigCode="cv"></mapping> 
     <mapping colour="Indigo" configCode="8" stConfigCode= "zx" dgConfigCode="vb"></mapping> 
     <mapping colour="Red" configCode="9" stConfigCode= "fg" dgConfigCode="cv"></mapping> 
    </model> 
</colourMappings> 

Je veux être en mesure de tirer tous les attributs et leurs valeurs données un nom de modèle et la couleur

par exemple

donné MODELY et blanc, je voudrais obtenir configCode = "1" stConfigCode = "xx" dgConfigCode = "hj" Cela pourrait être dans une structure - tableau, liste, quelle que soit

J'ai été en utilisant Linq en XML, mais ne peut pas obtenir la syntaxe correcte

XDocument mappings = XDocument.Load(@"D:\colour_mappings.xml"); 
var q = from c in mappings.Descendants("model") 
        where (string)c.Attribute("name") == "modelY" && (string)c.Descendants("mapping").Attributes("colour").FirstOrDefault() == "White" 
        select c.Attributes(); 

quelqu'un sait comment faire cela?

Heureux d'utiliser toute méthode, ne doit pas nécessairement être Linq

Répondre

5

Mise à jour

récapitulées dans un méthode:

public IEnumerable<XAttribute> GetAttributes(string modelName, string colour) 
{ 
    XDocument mappings = XDocument.Load(@"D:\colour_mappings.xml"); 

    var q1 = 
     from elm in mappings.Descendants("model") 
     where (string)elm.Attribute("name") == "modelY" 
     select elm; 

    var q2 = 
     from elm in q1.Descendants("mapping") 
     where (string)elm.Attribute("colour") == "White" 
     select elm.Attributes().Where(a => a.Name != "colour"); 


    foreach (IEnumerable<XAttribute> attributeList in q2) 
    { 
     foreach (XAttribute attribute in attributeList) 
     { 
      yield return attribute; 
     } 
    } 
} 
+0

merci - ce n'est pas exactement ce dont j'ai besoin cependant. Votre seul retourne tous les attributs de chaque cartographie Je veux juste les attributs pour le mappage simple dans ModelY qui a une couleur de blanc Décidé de le faire comme une requête en deux étapes - voir ci-dessous – ChrisCa

+0

@Christo Fur: Désolé, mon erreur , juste mis à jour le code de sorte qu'il devrait fonctionner maintenant :) –

+0

merci - Je suis arrivé à la même conclusion que vous et l'avez fait en 2 étapes – ChrisCa

1

que je suis pressé par le temps je vais utiliser un processus en 2 étapes

Mais serait intéressé d'entendre si cela est possible dans une requête

var matchingModelXml = from c in mappings.Descendants("model") 
           where (string)c.Attribute("name") == "modelY" 
           select c; 

var mappingAttributes = from b in matchingModelXml.Descendants("mapping") 
         where (string)b.Attribute("colour") == "White" 
         select b.Attributes(); 
1

Juste parce que j'aime un défi, ici il est dans une requête:

XDocument test = XDocument.Parse("<colourMappings> <model name=\"modelX\">  <mapping colour=\"White\" configCode=\"1\"></mapping>  <mapping colour=\"Aluminium\" configCode=\"2\"></mapping>  <mapping colour=\"Black\" configCode=\"3\"></mapping>  <mapping colour=\"Blue\" configCode=\"4\"></mapping>  <mapping colour=\"White Pearl\" configCode=\"5\"></mapping>  <mapping colour=\"Graphite\" configCode=\"6\"></mapping>  <mapping colour=\"Gunmetal\" configCode=\"7\"></mapping>  <mapping colour=\"Indigo\" configCode=\"8\"></mapping>  <mapping colour=\"Red\" configCode=\"9\"></mapping> </model> <model name=\"modelY\">  <mapping colour=\"White\" configCode=\"1\" stConfigCode= \"xx\" dgConfigCode=\"hj\"></mapping>  <mapping colour=\"Aluminium\" configCode=\"2\" stConfigCode= \"xy\" dgConfigCode=\"gh\"></mapping>  <mapping colour=\"Black\" configCode=\"3\" stConfigCode= \"xt\" dgConfigCode=\"fg\"></mapping>  <mapping colour=\"Blue\" configCode=\"4\" stConfigCode= \"sd\" dgConfigCode=\"fg\"></mapping>  <mapping colour=\"White Pearl\" configCode=\"5\" stConfigCode= \"df\" dgConfigCode=\"df\"></mapping>  <mapping colour=\"Graphite\" configCode=\"6\" stConfigCode= \"xc\" dgConfigCode=\"df\"></mapping>  <mapping colour=\"Gunmetal\" configCode=\"7\" stConfigCode= \"cv\" dgConfigCode=\"cv\"></mapping>  <mapping colour=\"Indigo\" configCode=\"8\" stConfigCode= \"zx\" dgConfigCode=\"vb\"></mapping>  <mapping colour=\"Red\" configCode=\"9\" stConfigCode= \"fg\" dgConfigCode=\"cv\"></mapping> </model></colourMappings>"); 

var maps = from model in test.Root.Elements("model") 
      from attr in model.Attributes("name") 
      from mapping in model.Elements("mapping") 
      where attr.Value == "modelY" && mapping.Attribute("colour").Value == "White" 
      select new 
      { 
       configCode = mapping.Attribute("configCode").Value 
       , stConfigCode = mapping.Attribute("stConfigCode").Value 
       , dgConfigCode = mapping.Attribute("dgConfigCode").Value 
      }; 

foreach (var map in maps) 
{ 
    Console.Write("configCode: "); 
    Console.WriteLine(map.configCode); 
    Console.Write("stConfigCode: "); 
    Console.WriteLine(map.stConfigCode); 
    Console.Write("dgConfigCode: "); 
    Console.WriteLine(map.dgConfigCode); 
} 
+0

Nice :) Seulement besoin de supprimer l'attribut «couleur», mais c'est facile :) –

+0

Juste fait quelques temps et il semble que votre seule requête est de 50 à 60% plus lent sur ce petit ensemble d'échantillons. Je pense que la raison en est que ces 4 "de" résultats dans beaucoup d'énumération. Mais encore une belle requête :) –

+0

Merci. Je devrais probablement avoir mentionné que j'ai seulement écrit ceci pour m'amuser. J'irais aussi sur la route des deux requêtes. C'est plus facile à lire et plus rapide :) –

0

Je sais que c'est ancienne, mais je pense que la façon de résoudre ce problème sans faire plus de traitement que les regards neccessary quelque chose comme ceci:

mappings.Root.Elements() 
     .Where(cm => cm.Attribute("name").Value == "modelY") 
     .SelectMany(cm => cm.Elements() 
          .Where(m => m.Attribute("colour").Value == "White") 
          .SelectMany(m => m.Attributes())); 

Dans le format de requête, ce serait:

from cm in doc.Root.Elements() 
where cm.Attribute("name").Value == "modelY" 
from m in cm.Elements() 
where m.Attribute("colour").Value == "White" 
from att in m.Attributes() 
select att; 
Questions connexes