Remco
Remco

Reputation: 279

Remove node from xmlDoc, how to delete the parentNode?

I have an xmlDoc, this is a part of it:

<Main>
<Set>
    <MId>1</MId>
    <RName>
        <MetaData>
            <PrdctName>
                Test 1
            </PrdctName>
        </MetaData>
    </RName>
</Set>  
<Set>
    <MId>1</MId>
    <RName>
        <MetaData>
            <PrdctName>
                Test 2
            </PrdctName>
        </MetaData>
    </RName>
</Set>
<Set>
    <MId>1</MId>
    <RName>
        <MetaData>
            <PrdctName>
                Test 3
            </PrdctName>
        </MetaData>
    </RName>
</Set>
<Set>
    <MId>2</MId>
    <RName>
        <MetaData>
            <PrdctName>
                Test 1
            </PrdctName>
        </MetaData>
    </RName>
</Set>
</Main>

By selecting an prdctName the rest has to be removed from the xmlDoc. For example if I choose for "Test 1" the result has to be:

<Main>
<Set>
    <MId>1</MId>
    <RName>
        <MetaData>
            <PrdctName>
                Test 1
            </PrdctName>
        </MetaData>
    </RName>
</Set>  
<Set>
    <MId>2</MId>
    <RName>
        <MetaData>
            <PrdctName>
                Test 1
            </PrdctName>
        </MetaData>
    </RName>
</Set>
</Main>

The problem is that I don't know how to remove the tag. So after a remove the xml looks now like:

<Main>
<Set>
    <MId>1</MId>
    <RName>
        <MetaData>
            <PrdctName>
                Test 1
            </PrdctName>
        </MetaData>
    </RName>
</Set>
<Set/>
<Set/>
<Set>
    <MId>2</MId>
    <RName>
        <MetaData>
            <PrdctName>
                Test 1
            </PrdctName>
        </MetaData>
    </RName>
</Set>
</Main>

Which code do I have to write to delete the tag also?

This is a part of the code I use now:

foreach (XmlNode chkNode in nodes)
{                
            string currentName = "Test 1";
            if (!nameDict.ContainsKey(currentName))                                    
                    chkNode.ParentNode.RemoveAll();
}

Upvotes: 0

Views: 7923

Answers (3)

Shailendra Mishra
Shailendra Mishra

Reputation: 71

you can try like this..

1) read the tag and copy all child node using inner xml.

2) now go to the root node that is MainParents.

3) now replace the inner xml string with your xml string which is read in first step.

Upvotes: 0

psubsee2003
psubsee2003

Reputation: 8741

I think your issue is the XmlNode.RemoveAll() only removing the children of the node and the chkNode.ParentNode property is selecting the node with the <Set> tag. So when you remove all children, you are left with an empty <Set/> node. You need to be able to remove that specific node as well.

To adapt your existing method, you need to do something like:

foreach (XmlNode chkNode in nodes)
{                
    string currentName = "Test 1";
    if (!nameDict.ContainsKey(currentName))
    {
        XmlNode parent = chkNode.ParentNode;
        parent.ParentNode.RemoveChild(parent);
    }
}

Of course, I can't test this as-is since I am not sure what exactly nameDict and nodes are.

For the sake of completeness, this code will break if chkNode or chkNode.ParentNode are XmlNodes that cannot have parents (such as a Attribute, Document, DocumentFragment, Entity, Notation nodes). If you think this is a possible scenario, you might want to include the appropriate null checks or wrap this method in a try-catch

Something like:

XmlNode parent = chkNode.ParentNode;
if (parent != null && parent.ParentNode != null)
    parent.ParentNode.RemoveChild(parent);

Or:

try
{
    XmlNode parent = chkNode.ParentNode;
    parent.ParentNode.RemoveChild(parent);
}
catch (NullReferenceException ex)
{
    // do something with exception
}

There are several options with LINQ to accomplish what you want in a better way, but since you are using C#2.0, this solution should get you in the right direction.

Upvotes: 4

user854301
user854301

Reputation: 5483

It could be done with help of linq to xml and xpath. Find example below:

    var xdocument = XDocument.Parse(xml)
    xdocument.Document.Root.Elements()
   .Where(element 
       => !element.XPathSelectElement("RName/MetaData/PrdctName").Value.Contains("Test 1"))
   .Remove();
   // saving results...
   xdocument.Save("somewhere.xml");

PS

Not so good to check on contains Value.Contains("Test 1")but here don't see any others solutions for it.

Upvotes: 0

Related Questions