How to combine node values from different nodes into one node separated with a "/" every 2 values

Viewed 114

I have the following XML:

 <root>
        <table>
            <items>Item 1</items>
            <values>value 1></values>
        </table>
        <table>
            <items>Item 2</items>
            <values>value 2></values>
        </table>
        <table>
            <items>Item 3</items>
            <values>value 3></values>
        </table>
        <table>
            <items>Item 4</items>
            <values>value 4></values>
        </table>
        <table>
            <items>Item 5</items>
            <values>value 5></values>
        </table>
        <table>
            <items>Item 6</items>
            <values>value 6></values>
        </table>
        <table>
            <items>Item 7</items>
            <values>value 7></values>
        </table>
        <table>
            <items>Item 8</items>
            <values>value 8></values>
        </table>
    </root>

Now, what I want is to add a new node to my XML in which all values are stored, separated by a "/" every 2 values. The new node will look like this:

<combined>Item 1, value 1 / Item 2, value 2 / Item 3, value 3 / Item 4, value 4 / Item 5, value 5/ Item 6, value 6 / Item 7, value 7 / Item 8, value 8</combined>

I managed to do this with only the items node, but how can I get the above result? This is my script so far:

string text = File.ReadAllText(instance.Folder.InputFile.FullName);

XDocument doc = XDocument.Parse(text);
XElement root = doc.Root;
XElement Table= root.Element("Table");
Table.Add(new XElement("combined"));
XElement combined = Table.Element("combined");

string[] data = doc.Descendants("items").Select(x => (string)x).ToArray();

string splitData = string.Join(" / ", data.Select((x, i) => new { data = x, index = i }).GroupBy(x => x.index / 2).Select(x => string.Join(" , ", x.Select(y => y.data))));

combined.Add(splitData);

doc.Save(instance.Folder.InputFile.FullName);

Who can help me out?

1 Answers

Rather than finding all the items elements, I would look for the parent table elements first, then consider this in terms of a query pipeline:

  • Find all table elements
  • Within each element, find the items and values elements and grab their values as strings
  • Transform each pair of string to a comma-separated pair
  • Use string.Join to build those together

For example:

var doc = XDocument.Load("test.xml");
var commaSeparated = doc
    .Descendants("table")
    .Select(x => new { Items = x.Element("items").Value, Values = x.Element("values").Value })
    .Select(pair => $"{pair.Items}, {pair.Values}");
var result = string.Join(" / ", commaSeparated);

With the XML you've shown, that gives a result of:

Item 1, value 1> / Item 2, value 2> / Item 3, value 3> / Item 4, value 4> / Item 5, value 5> / Item 6, value 6> / Item 7, value 7> / Item 8, value 8>

Note that the additional > characters are present in your XML in the question.

Related