2

Given the following XML example

<aaa>
    <bbb id="1">
        <ccc att="123"/>
        <ccc att="456"/>
        <ccc att="789"/>
    </bbb>
    <bbb id="2">
        <ccc att="321"/>
        <ccc att="654"/>
        <ccc att="987"/>
    </bbb>
</aaa>

as an XmlDocument object called xDoc1, I managed to remove the first bbb node thanks to its ID and an XPath instruction, leaving the second bbb node alone in the aaa one.

But now I want to get this removed node and its markups in a single string, as the InnerText value of this node is equal to

<ccc att="123"/><ccc att="456"/><ccc att="789"/>

but I want my string to be equal to

<bbb id='1'><ccc att="123"/><ccc att="456"/><ccc att="789"/></bbb>

How can I do so ? Using XmlDocument is mandatory.

I tried to use the ParentNode method, but then it includes the other bbb node.

My C# code for the moment :

xDoc1 = new XmlDocument();
xDoc1.Load("file.xml"); // Containing the given example above.

XmlNodeList nodes = xDoc1.SelectSingleNodes("//bbb[@id='1']");

foreach (XmlNode n in nodes)
{
    XmlNode parent = n.ParentNode;
    parent.RemoveChild(n);
}

// At this point, xDoc1 does not contain the first bbb node (id='1') anymore.
Thesaurus Rex
  • 123
  • 1
  • 8

2 Answers2

5

Use OuterXml property of XmlNode

xDoc1 = new XmlDocument();
xDoc1.Load("file.xml"); // Containing the given example above.

XmlNodeList nodes = xDoc1.SelectSingleNodes("//bbb[@id='1']");

foreach (XmlNode n in nodes)
{
    XmlNode parent = n.ParentNode;
    parent.RemoveChild(n);
    Console.WriteLine(n.OuterXml);
}
Viru
  • 2,228
  • 2
  • 17
  • 28
1

I would firstly suggest not using XmlDocument. It's old tech and has been superseded by XDocument, which gives you Linq2Xml and lots of explicit casting goodness when dealing with attributes etc.

Using the XDocument approach with Linq instead of XPath, it's quite a lot easier to work this problem:

var doc=XDocument.Load("file.xml");
var elToRemove = doc.Root.Elements("bbb").Single(el => (int)el.Attribute("id") == 1);
elToRemove.Remove();

Console.WriteLine(doc.ToString()); //no <bbb id="1">
Console.WriteLine(elToRemove.ToString()); //the full outer text of the removed <bbb>
Community
  • 1
  • 1
spender
  • 117,338
  • 33
  • 229
  • 351
  • OP also wants three child nodes "" in removed element...probably you should update your answer to include that too – Viru Feb 03 '16 at 15:10
  • @Viru I don't understand what you are asking me to include. The descendants of the removed element remain unchanged (i.e. they are removed when the tag is removed by virtue of being children). – spender Feb 03 '16 at 15:12
  • 1
    Problem is that XmlDocument is used everywhere else in the project, and I must keep using it. I'm sorry I didn't specify it, editing my question. Thank you for your answer though. – Thesaurus Rex Feb 03 '16 at 15:16