Reputation: 279
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
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
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
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