I’m stuck with using a web service I have no control over and am trying to parse the XML returned by that service into a standard object.
A portion of the XML structure looks like this
<NO> <L>Some text here </L> <L>Some additional text here </L> <L>Still more text here </L> </NO>
In the end, I want to end up with one String property that will look like ‘Some text here Some additional text here Still more text here ‘
What I have for an initial pass is what follows. I think I’m on the right track, but not quite there yet:
XElement source = \\Output from the Webservice List<IndexEntry> result; result = (from indexentry in source.Elements(entryLevel) select new IndexEntry() { EtiologyCode = indexentry.Element('IE') == null ? null : indexentry.Element('IE').Value, //some code to set other properties in this object Note = (from l in indexentry.Elements('NO').Descendants select l.value) //This is where I stop // and don't know where to go }
I know that I could add a ToList() operator at the end of that query to return the collection. Is there an opertaor or technique that would allow me to inline the concatentation of that collection to a single string?
Feel free to ask for more info if this isn’t clear.
Thanks.
LINQ to XML is indeed the way here:
EDIT: Based on the comment, it looks like you just need a single-expression way of representing this. That’s easy, if somewhat ugly:
Another alternative is to extract it into a separate extension method (it has to be in a top-level static class):
then change your code to:
EDIT: A note about efficiency
Other answers have suggested using
StringBuilderin the name of efficiency. I would check for evidence of this being the right way to go before using it. If you think about it,StringBuilderandToArraydo similar things – they create a buffer bigger than they need to, add data to it, resize it when necessary, and come out with a result at the end. The hope is that you won’t need to resize too often.The difference between
StringBuilderandToArrayhere is what’s being buffered – inStringBuilderit’s the entire contents of the string you’ve built up so far. WithToArrayit’s just references. In other words, resizing the internal buffer used forToArrayis likely to be cheaper than resizing the one forStringBuilder, particularly if the individual strings are long.After doing the buffering in
ToArray,string.Joinis hugely efficient: it can look through all the strings to start with, work out exactly how much space to allocate, and then concatenate it without ever having to copy the actual character data.This is in sharp contrast to a previous answer I’ve given – but unfortunately I don’t think I ever wrote up the benchmark.
I certainly wouldn’t expect
ToArrayto be significantly slower, and I think it makes the code simpler here – no need to use side-effects etc, aggregation etc.