-1

I have an XML document, where I need to add and remove some nodes while iterating through. But if I'll add nodes like that, the other nodes will be shifted depending on InsertAfter or RemoveChild. So xNode.ChildNodes[i] will point to the wrong node. Of course, I can add or substract counter, but I think it's not a best way. How should I do this?

void Init()
{
    XmlDocument doc = LoadDocument("test.xml");
    RecursiveProcess(doc);
}

void RecursiveProcess(XmlNode xNode)
{
    for(int i = 0; i < node.ChildNodes.Count; i++)
    {
        XmlElement node = xNode.ChildNodes[i] as XmlElement;

        if(/*some condition*/)
        {
            var x = Document.CreateElement("newNode");
            node.ParentNode.InsertAfter(x, node);
        }
        else if(...)
        {
            var x = Document.CreateElement("anotherNode");
            node.ParentNode.RemoveChild(node);
        }

        RecursiveProcess(node);
    }
}
MG_REX
  • 23
  • 6
  • Do you have any issue if the added node is processed? You can add the references of child nodes to another data structure and process them instead of looping through child nodes. This will be two loops instead of one. – Vijay Mar 15 '20 at 14:03
  • @Vijay, If i add node, it will pre processed, what I don't want. If i remove a few nodes, some other nodes will be skipped because they may be shifted up. – MG_REX Mar 15 '20 at 14:10
  • Why not keep things simple? Read all the data as is into some kind of structures. Process the internal data as required. Write out the revised set of internal data as XML. That is surely better than trying to do it on the fly. – Andrew Truckle Mar 15 '20 at 15:07
  • 1
    @AndrewTruckle because the document is very lagre (OpenXML). And I know about OpenXML library but gave an example with common xml to only reflect the essence of the issue – MG_REX Mar 15 '20 at 15:27
  • 1
    Have you considered using XSLT for this? It's designed for the job, and will be much less effort in the long run. – Michael Kay Mar 15 '20 at 16:20
  • Your issue is not an XML issue, but one with any list object where you are trying to add/delete at same time. First I would recommend going through loop twice. Once to add and another time to delete. When deleting I would start at end of object and move towards the beginning using a loop like : for(int i = x.list.Length - 1; i >= 0; i--){}. I don't know why you would need a recursive algorithm. For huge files I would use XmlReader. See sample of my code at : https://stackoverflow.com/questions/40456446/efficient-way-to-read-large-xml-into-dfferent-node-types-in-c-sharp – jdweng Mar 15 '20 at 18:29

1 Answers1

0

I've found a solution. I have created two queues

NodesToRemove = new Queue<OpenXmlElement>();
NodesToInsert = new Queue<Tuple<OpenXmlElement, OpenXmlElement, InsertMode>>();

And after main document processing I iterate throug the queues and do add/remove operations

MG_REX
  • 23
  • 6