2009-11-01 15 views
0

Je l'ai utilisé dans le passé pour construire des listes virgule: seperatedutiliser la fonction d'agrégat linq pour construire une chaîne xml?

var list = new List<int>{1,2,3}; 
var retVal = list.Select(i=>i.ToString()).Aggregate((a,b) => a+", "+b); 

Fonctionne très bien. J'essaie de faire le même genre de chose pour «envelopper» chaque élément en tant que nœud 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 y a-t-il un moyen plus facile entièrement?

Merci.

Répondre

2

devrait-il pas être comme:

Aggregate((a, b) => string.Format("{0}<ID>{1}</ID>", a,b)) 

Vous ajoutez à a nouveaux nœuds.

3

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 aussi plus efficace, même si cela ne sera important que pour les grandes listes.

3

Ou existe-t-il un moyen plus facile entièrement?

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); 
0

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 de création d'une chaîne CSV utilise l'opérateur de concaténation de chaîne; l'approche recommandée consiste à utiliser la classe StringBuilder à cette fin. Et dans .Net 4.0 il y a une nouvelle surcharge pour la méthode string.Join() qui est beaucoup plus simple à utiliser et à comprendre.

Si votre intention est de créer un document XML plutôt qu'une chaîne, puis la réponse de » David B 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 d'ouvrir le codage explicitement et fermeture des tags. Dans votre exemple, il serait difficile d'obtenir le nom d'élément "ID" incorrect dans les balises d'ouverture ou de fermeture, mais je pense à cela en termes de principe DRY. J'ai parfois oublié de modifier l'étiquette de fermeture d'un élément lorsque j'ai modifié l'étiquette d'ouverture, par exemple. dans les fichiers de configuration. L'utilisation 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() par rapport string.join(), string.join() gagne à chaque fois (avec le test limité assez/base cas que j'ai utilisé).

Questions connexes