Search code examples
c#xmlvisual-studioc#-4.0xmldocument

Add sibling after a specific XML node C#


My xml document looks like this:

<root>
<parent1>
    <element1>
    </element1>
</parent1>
<parent1>
    <element1>
    </element1>
</parent1>
<parent1>
    <element1>
    </element1>
</parent1>
<parent2>
    <element1>
    </element1>
</parent2>
<parent2>
    <element1>
    </element1>
</parent2>
<parent3>
    <element2>
    </element2>
</parent3>
</root>

I would like to add a new parent1 node after the last parent1 node before the first parent2 node.

Like this:

<root>
    <parent1>
        <element1>
        </element1>
    </parent1>
    <parent1>
        <element1>
        </element1>
    </parent1>
    <parent1>
        <element1>
        </element1>
    </parent1>
    <parent1>
        <element1>
        </element1>
    </parent1>
    <parent2>
        <element1>
        </element1>
    </parent2>
    <parent2>
        <element1>
        </element1>
    </parent2>
    <parent3>
        <element2>
        </element2>
    </parent3>
</root>

I tried with the XmlDocument SelectSingleNode and AppendChild methods but it only adds the new child after the last parent3 node.

EDIT:

I tried with this code:

string newNode = "<parent1/><element1>1</element1></parent1/>";

XmlDocumentFragment xmlDocFrag = xmlDocument.CreateDocumentFragment();
xmlDocFrag.InnerXml = newNode;


XmlElement element = (XmlElement)xmlDocument.SelectSingleNode(@"//root/parent1[last()]");


element.InsertAfter(xmlDocFrag, element); //--> this throws an error
element.AppendChild(xmlDocFrag); //--> this works but it inserts the new node inside the last parent1 node

Solution

  • you were pretty close, but the method you needed is InsertAfter which has to be used on parent. Take a look at this example (comments are in code)

    string xml = @"
        <root>
        <parent1>
            <element1>
            </element1>
        </parent1>
        <parent1>
            <element1>
            </element1>
        </parent1>
        <parent1>
            <element1>
            </element1>
        </parent1>
        <parent2>
            <element1>
            </element1>
        </parent2>
        <parent2>
            <element1>
            </element1>
        </parent2>
        <parent3>
            <element2>
            </element2>
        </parent3>
        </root>
        ";
    
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.LoadXml(xml);
    
    //you had invalid xml here. <parent1/> instead of <parent1> and </parent1/> instead of </parent1>
    string newNode = "<parent1><element1>1</element1></parent1>";
    
    XmlDocumentFragment xmlDocFrag = xmlDocument.CreateDocumentFragment();
    xmlDocFrag.InnerXml = newNode;
    
    XmlElement element = (XmlElement)xmlDocument.SelectSingleNode(@"//root/parent1[last()]");
    
    //once you found last parent1 element, find it's parent
    XmlNode parent = element.ParentNode;
    //now, use that parent element and it's InsertAfter method to add new node as sibling to your found element
    parent.InsertAfter(xmlDocFrag, element);