LINQ-to-XML littéraire: meilleure pratique pour désérialiser attribut / valeur en paires structurées variable / valeur

StackOverflow https://stackoverflow.com/questions/1214326

  •  06-07-2019
  •  | 
  •  

Question

Je tente de désérialiser le code XML suivant:

<?xml version="1.0" encoding="utf-8" ?>

<conf name="settings">

    <item name="lorem"
        one="the"
        two="quick"
        three="brown"
        four="fox"
        five="jumps"
        six="over"
        seven="the"
        eight="lazy"
        nine="dog"
            />

    <item name="ipsum"
        one="how"
        two="many"
        three="roads"
        four="must"
        five="a"
        six="man"
        seven="walk"
        eight="down"
        nine="?"
            />

</conf>

espérant le faire de la manière la plus élégante et la plus succincte en utilisant LINQ-to-XML, mais étant donné que je ne suis pas le plus intelligent des villes en matière de méthodes imbriquées, de types inférés, de génériques, etc. & # 233; tera, j'ai pensé que ce serait une bonne idée de demander si l'un de vous aimerait aller de l'avant et me montrer un peu d'alphabétisation LINQ:)

Pour le moment, je fais quelque chose comme:

XDocument config = XDocument.Load("whatever.conf");

var one = from q in config.Descendants("item")
            select (string)q.Attribute("one");

var two = from q in config.Descendants("item")
            select (string)q.Attribute("two");

Et je sais que je passe à côté de l’essentiel, non seulement parce que je me répète souvent, mais aussi parce que les requêtes ne fonctionnent que s’il n’ya qu’un élément, alors encore une fois si vous tout commentaire ou suggestion serait vraiment apprécié. Merci beaucoup d'avance!

UPDATE: au cas où l'exemple précédent ne serait peut-être pas très utile, voici un scénario plus réaliste:

<?xml version="1.0" encoding="utf-8" ?>

<conf name="ftp-settings" freq="daily" time="23:00">
    <item   name="isis"
            host="10.10.1.250"
            user="jdoe"
            pass="4/cB0kdFGprXR/3oTs8mtw=="
            file="backup.tar.gz"
            path="/var/log"
        />
    <item   name="seth"
            host="10.10.2.250"
            user="jdoe"
            pass="4/cB0kdFGprXR/3oTs8mtw=="
            file="backup.tar.gz"
            path="/var/log"
        />
</conf>

Par conséquent, pour chacun de ces éléments, j'aimerais générer des variables afin de pouvoir les transmettre en tant que paramètres d'une méthode de gestion FTP.

RESOLU:

C’était aussi simple que de foreach :

var elements = from element in xml.Descendants("item") select element;

foreach (XElement item in elements) {
    ftp.DownloadFile(
        item.Attribute("host").Value,
        item.Attribute("user").Value,
        item.Attribute("pass").Value,
        item.Attribute("file").Value,
        item.Attribute("path").Value
        );
}
Était-ce utile?

La solution

Normalement, je m'attendrais à vouloir une seule représentation de chaque élément, plutôt qu'une séquence de & "One &"; valeurs et une autre séquence de & "; deux &"; valeurs. En d'autres termes, je m'attendrais à quelque chose comme:

var items = config.Descendants("item")
                  .Select(element => Item.FromXElement(element));

Si vous avez beaucoup d'attributs dans un seul élément, je trouve utile de séparer le & "créer un objet à partir de cet élément &"; code dans sa propre méthode (dans ce cas Item.FromXElement) plutôt que de tout insérer dans la requête. Si Item ne doit pas connaître sa représentation LINQ to XML, placez la méthode quelque part qui devrait:)

items est alors un IEnumerable<Item> que vous pouvez convertir en liste ou tout autre chose que vous voulez faire.

Bien sûr, cela dépend vraiment de ce que vous essayez de faire - et nous ne savons pas vraiment ce que cela représente. Peut-être pouvez-vous vraiment vouloir vouloir chaque & "Séquence d'attributs &"; séparément ...

<=> ressemblerait à quelque chose comme:

public static Item FromXElement(XElement element)
{
    string name = (string) element.Attribute("name");
    string host = (string) element.Attribute("host");
    // etc
    return new Item(name, host, ...);
}

(Vous devez évidemment créer un constructeur avec les paramètres appropriés.)

Autres conseils

Je voudrais faire ceci:

XDocument config = XDocument.Load("whatever.conf");

var pairs = from q in config.Descendants("item")
           select new {
               One = (string)q.Attribute("one"),
               Two = (string)q.Attribute("two") };

var ones = pairs.Select(pair => pair.One);
var twos = pairs.Select(pair => pair.Two);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top