Insert an XML fragment after the last specific node / element

I want to add an XML fragment to the last element in an XML document, and I'm having problems, that is, the error I get:

"The node link is not a child of this node."

So my existing XML document is as follows:

<MAP> <LAYER name ="My first Layer"> <DATASET name="foo dataset" /> <SYMBOLOGY> <SYMBOL colour="red" /> </SYMBOLOGY> </LAYER> <LAYER name="My second Layer"> <DATASET name="bar dataset" /> <SYMBOLOGY> <SYMBOL colour="blue" /> </SYMBOLOGY> </LAYER> </MAP> 

The XML fragment that I want to insert after the last LAYER element:

 <LAYER name="My third Layer"> <DATASET name="whatever dataset" /> <SYMBOLOGY> <SYMBOL colour="yellow" /> </SYMBOLOGY> </LAYER> 

The code I use is:

 XmlDocumentFragment xmlDocFrag = xmlDocument.CreateDocumentFragment(); xmlDocFrag.InnerXml = inputXML; //which is basically the third layer example - see above. XmlElement rootElement = xmlDocument.DocumentElement; XmlNode lastLayerNode = rootElement.SelectSingleNode(@"//LAYER[last()]"); rootElement.InsertAfter(xmlDocFrag, lastLayerNode); //error raised here. 

Any ideas on what I am doing wrong would be greatly appreciated. My XPath query seems to find, and it seems that it is choosing the right last layer, which it simply won't paste after it for some bizarre reason.

UPDATE / SOLUTION - How to do it with XPATH

Finally, it turned out that in XPath - see the code below, I think that basically there was no choice of the correct parent node in the first place, it is wrong to select the last LAYER, and then try InsertAfter () on this node. It is better to choose a level higher, i.e. MAP, then AppendChild (). See below:

 XmlDocumentFragment xmlDocFrag = xmlDocument.CreateDocumentFragment(); xmlDocFrag.InnerXml = inputXML; XmlElement mapElement = (XmlElement)xmlDocument.SelectSingleNode(@"//MAP[last()]"); mapElement.AppendChild(xmlDocFrag); 

Thanks to all the answers and help :)

+2
source share
3 answers

Whereas you need this to work with Framework 2.0, here is another solution:

 string xml = "<map><layer>1</layer><layer>2</layer></map>"; string addMe = "<layer>3</layer>"; XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(xml); XmlDocumentFragment xmlDocFrag = xmlDocument.CreateDocumentFragment(); xmlDocFrag.InnerXml = addMe; XmlElement rootElement = xmlDocument.DocumentElement; rootElement.AppendChild(xmlDocFrag); 

This leads to:

 <map><layer>1</layer><layer>2</layer><layer>3</layer></map> 
+5
source

Everything looks good, but first I will try to avoid choosing xpath for the last node, but instead just use this:

 rootElement.InsertAfter(xmlDocFrag, rootElement.LastChild); 
0
source

I had a similar problem, I used the ImportNode method to solve it

Here is a small example of how you can use it to add a node from another xml (stored in a string) to your example with the desired node in the xml tree

 string xmlstring =@ "<tag>.....</tag>"; // holds xml tree to be appended XmlDocument xml2 = new XmlDocument(); xml2.Load(@"path_of_main_xml"); XmlDocument xml1 = new XmlDocument(); xml1.Load(new StringReader(xmlString)); // get the node you want to import which in this icase is string XmlNode elem = xml1.DocumentElement; // use importNode to import it XmlNode impnode = xml2.ImportNode(elem,true); // get the node list of all node of particular tag name XmlNodeList eNode = xml2.GetElementsByTagName("tag_name_of_parent"); eNode[0].AppendChild(impnode); // append new node // write back the updates to same file XmlWriter writer = XmlWriter.Create(@"path_of_main_xml"); xml2.Save(writer); 
0
source

Source: https://habr.com/ru/post/1496753/


All Articles