Search code examples
c#.netxmlparent-childxmldocument

How do I put child nodes into their own parent node?


I have the following XML input:

<init>
   <options>
      <option>1</option>
      <option>2</option>
      <option>3</option>
   </options>
</init>

I would like to transform this into the following output XML:

<init>
    <options>
       <option>1</option>
    </options>
    <options>
       <option>2</option>
    </options>
    <options>
       <option>3</option>
    </options>
</init>

So instead of one <options> tag, I want to create multiple <options> tags based on the amount of child nodes within the input XML.

I'm using XmlDocument in C# .NET.

What is the easiest way to do this?


Solution

  • Assuming the format exactly you have provided

    var xmlStr = @"<init>
                      <options>
                         <option>1</option>
                         <option>2</option>
                         <option>3</option>
                      </options>
                   </init>";
            var xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xmlStr);
    
            var resultDoc = new XmlDocument();
            resultDoc.LoadXml("<init></init>");
            XmlElement elem;
    
            foreach (XmlElement node in xmlDoc.FirstChild.FirstChild.ChildNodes)
            {
                elem = resultDoc.CreateElement("options");
                resultDoc.FirstChild.AppendChild(elem);
    
                elem = resultDoc.CreateElement("option");
                elem.InnerText = node.InnerText;
                resultDoc.FirstChild.LastChild.AppendChild(elem);
            }
    
    Console.WriteLine(resultDoc.InnerXml);
    

    Edit: Instead of creating new XmlDocument, you can use the same document and reorder your elements. I hope this is what you meant.

    xmlDoc.LoadXml(xmlStr);
    
    xmlDoc.FirstChild.InnerXml = string.Join("", 
        xmlDoc.SelectNodes("//option")
        .Cast<XmlNode>()
        .Select(n => n.OuterXml));
    
    XmlElement elem;
    foreach (XmlElement node in xmlDoc.SelectNodes("//init//option"))
    {
        xmlDoc.FirstChild.RemoveChild(node);
        elem = xmlDoc.CreateElement("options");
        elem.AppendChild(node);
        xmlDoc.FirstChild.AppendChild(elem);
    }