Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception occured while tried to use 'InsertBefore' of XmlDocument in C#

Tags:

c#

xml


I was trying to insert a xml node before another xmlnode and I have got an exception saying "The reference node is not a child of this node."

This is my initial xml :

<?xml version="1.0" encoding="utf-8" ?>
<Details xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <sampleData>
    <otherNodes></otherNodes>
  </sampleData>
</Details>

I wanted to insert following xml datas(b:dataTobeInserted1,b:dataTobeInserted2 and b:dataTobeInserted3) as a Child of Details but before sampleData.

Details1.xml

<?xml version="1.0" encoding="utf-8" ?>
<DataInserted1 xmlns:b="http://example.com/data">
  <b:dataTobeInserted1>
    <b:otherDetails1></b:otherDetails1>
  </b:dataTobeInserted1>
</DataInserted1>

Details2.xml

<?xml version="1.0" encoding="utf-8" ?>
<DataInserted2 xmlns:b="http://example.com/data">
  <b:dataTobeInserted2>
    <b:otherDetails2></b:otherDetails2>
  </b:dataTobeInserted2>
</DataInserted2>

Details3.xml

<?xml version="1.0" encoding="utf-8" ?>
<DataInserted3 xmlns:b="http://example.com/data">
  <b:dataTobeInserted3>
    <b:otherDetails3></b:otherDetails3>
  </b:dataTobeInserted3>
</DataInserted3>

I want my Output as

<?xml version="1.0" encoding="utf-8" ?>
<Details xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"  xmlns:b="http://example.com/data">
  <b:dataTobeInserted1>
    <b:otherDetails1></b:otherDetails1>
  </b:dataTobeInserted1>
  <b:dataTobeInserted2>
    <b:otherDetails2></b:otherDetails2>
  </b:dataTobeInserted2>
  <b:dataTobeInserted3>
    <b:otherDetails3></b:otherDetails3>
  </b:dataTobeInserted3>
  <sampleData>
    <otherNodes></otherNodes>
  </sampleData>
</Details>

This is what I did to achieve my desired output.

    XmlDocument xmldoc = new XmlDocument();
    xmldoc.Load(@"..\..\initial-Doc.xml");

    xmldoc.DocumentElement.SetAttribute("xmlns:b", "http://example.com/data");


        XmlDocument detail1 = new XmlDocument();
        detail1.Load(@"..\..\DataToBeInserted1.xml");
        XmlNode detail1Node = xmldoc.ImportNode(detail1.DocumentElement, true);

        XmlDocument detail2 = new XmlDocument();
        detail2.Load(@"..\..\DataToBeInserted2.xml");
        XmlNode detail2Node = xmldoc.ImportNode(detail2.DocumentElement, true);

        XmlDocument detail3 = new XmlDocument();
        detail3.Load(@"..\..\DataToBeInserted3.xml");
        XmlNode detail3Node = xmldoc.ImportNode(detail3.DocumentElement, true);

    xmldoc.InsertBefore(detail1Node, xmldoc.DocumentElement.FirstChild);
    xmldoc.InsertBefore(detail2Node, xmldoc.DocumentElement.FirstChild);
    xmldoc.InsertBefore(detail3Node, xmldoc.DocumentElement.FirstChild);

    xmldoc.Save(@"..\..\initial-Doc-new.xml");

Is the new namespace is causing the problem?Please tell me where I went wrong.

Thanks Alex

like image 670
wizzardz Avatar asked Nov 09 '10 10:11

wizzardz


2 Answers

Looks to me like the problem is exactly what the exception says: "The reference node is not a child of this node." The only tricky part is figuring out which nodes they're referring to. :-)

Here "this node" means the XmlNode whose InsertBefore() method you're calling, and "the reference node" means the second argument to InsertBefore(). So in the following line:

xmldoc.InsertBefore(detail1Node, xmldoc.DocumentElement.FirstChild);

It's saying that xmldoc.DocumentElement.FirstChild is not a child of xmldoc.

Which is true. xmldoc.DocumentElement.FirstChild is a child of xmldoc.DocumentElement.

So if you change that line to the following, the problem should be fixed:

xmldoc.DocumentElement.InsertBefore(detail1Node, xmldoc.DocumentElement.FirstChild);
like image 117
LarsH Avatar answered Sep 20 '22 12:09

LarsH


You need to make a copy of the node, for you cannot add an xml node from one document to another.

I think copying the node using the CloneNode() method should be enough, but if that fails you could create a new node from the nodes InnerXml or OuterXml property.

like image 29
Rune Grimstad Avatar answered Sep 19 '22 12:09

Rune Grimstad