utiliser la fonction LINQ globale pour construire la chaîne xml?
Question
Je l'ai utilisé dans le passé pour construire des listes séparées par des virgules:
var list = new List<int>{1,2,3};
var retVal = list.Select(i=>i.ToString()).Aggregate((a,b) => a+", "+b);
Fonctionne très bien.
Je suis en train de faire le même genre de chose à «envelopper chaque élément comme un noeud XML.
Quelque chose comme:
Aggregate((a, b) => string.Format("<ID>{0}</ID><ID>{1}</ID>", a,b))
peut ne pas sembler tout à fait pour le faire fonctionner bien. C'est possible? Ou est-il tout à fait un moyen plus facile?
Merci.
La solution
devrait-il pas être comme:
Aggregate((a, b) => string.Format("{0}<ID>{1}</ID>", a,b))
Vous ajoutez à a
nouveaux nœuds.
Autres conseils
La réponse de Blindy va certainement travailler, mais je préfère personnellement utiliser:
var list = new List<int> {1, 2, 3};
var joined = string.Join("", list.Select(x => "<ID>" + x + "</ID>")
.ToArray());
Personnellement, je trouve que plus facile à lire et à comprendre que l'agrégation. Je crois que ce sera plus efficace, aussi - bien que cela ne fera que la matière pour les grandes listes
.Ou est-il tout à fait un moyen plus facile?
List<int> list = new List<int>{1, 2, 3};
var xmlNodes = list.Select(i => new XElement("ID", i));
XElement xml = new XElement("Data", xmlNodes);
Console.WriteLine(xml);
Il y a plusieurs façons d'y parvenir, mais je soupçonne que la bonne réponse est « ça dépend ». Votre exemple original pour créer une chaîne CSV utilise l'opérateur de concaténation de chaîne; l'approche recommandée est d'utiliser le StringBuilder classe à cet effet. Et en .Net 4.0 il y a une nouvelle surcharge pour le string.join () méthode qui est beaucoup plus simple à utiliser et à comprendre.
// .Net 3.5
var list = new List<int>{1,2,3};
var csv = list.Aggregate(new StringBuilder(),
(sb, i) => sb.Append(i).Append(','),
sb => { if (sb.Length > 0) sb.Length--; return sb.ToString(); });
// .Net 4.0
var csv1 = string.Join(",", list);
Si votre intention est de créer un document XML plutôt qu'une chaîne puis David B réponse de l ' de ci-dessus est une bonne option:
var xml = new XElement("Root", list.Select(i => new XElement("ID", i)));
// <Root>
// <ID>1</ID>
// <ID>2</ID>
// <ID>3</ID>
// </Root>
Pour créer des chaînes XML que je préfère éviter le codage explicitement balises d'ouverture et de fermeture. Dans votre exemple, il serait difficile d'obtenir le nom élément « ID » incorrect dans les deux balises d'ouverture ou de fermeture, mais je pense à cela en termes de principe SEC. À l'occasion, je l'ai oublié de modifier la balise de fermeture d'un élément quand je l'ai modifié la balise d'ouverture par exemple dans les fichiers de configuration. En utilisant XElement évite cette question complètement:
// .Net 3.5
var xml1 = list.Aggregate(new StringBuilder(),
(sb, i) => sb.Append(new XElement("ID", i)),
sb => sb.ToString());
// .Net 4.0
var xml2 = string.Join("", list.Select (i => new XElement("ID", i)));
// both xml1 & xml2 contain "<ID>1</ID><ID>2</ID><ID>3</ID>"
Performance de Aggregate () contre string.join () , string.join () gagne à chaque fois (avec assez limitée / cas de test de base je).