0

I've used this in the past to build comma seperated lists:

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

Works great.

I'm trying to do the same sort of thing to 'wrap' each element as an xml node.

Something like:

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

Can't quite seem to make it work though. Is it possible? Or is there an easier way entirely?

Thanks.

4 Answers 4

3

Blindy's answer will certainly work, but I'd personally use:

var list = new List<int> {1, 2, 3};
var joined = string.Join("", list.Select(x => "<ID>" + x + "</ID>")
                                 .ToArray());

I personally find that easier to read and understand than the aggregation. I believe it will be more efficient, too - although that will only matter for large lists.

Sign up to request clarification or add additional context in comments.

Comments

3

Or is there an easier way entirely?

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

Comments

2

Shouldn't it be like:

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

You're adding to a new nodes.

Comments

0

There are a number of ways to achieve this but I suspect the correct answer is "it depends". Your original example for creating a CSV string uses the string concatenation operator; the recommended approach is to use the StringBuilder class for this purpose. And in .Net 4.0 there is a new overload for the string.Join() method that is a whole lot simpler to use and understand.

// .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);

If your intention is to create an XML Document rather than a string then David B's answer above is a good option:

var xml = new XElement("Root", list.Select(i => new XElement("ID", i)));
// <Root>
//   <ID>1</ID>
//   <ID>2</ID>
//   <ID>3</ID>
// </Root> 

For creating XML strings I prefer to avoid explicitly coding opening and closing tags. In your example it would be difficult to get the element name "ID" incorrect in either opening or closing tags but I think of this in terms of the DRY principle. On occasion I have forgotten to modify the closing tag for an element when I have modified the opening tag e.g. in config files. Using XElement avoids this issue completely:

// .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 of Aggregate() versus string.Join(), string.Join() wins every time (with the fairly limited/basic test case I used).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.