Linq to XML
-
Hi all, I have a XML file like below <root> <child> <no>1</no> <name>a</name> </child> <child> <no>2</no> <name>b</name> </child> <child> <no>3</no> <name>c</name> </child> </root> I want to delete the paticular node(Completely, including its parent node). For example <child> <no>1</no> <name>a</name> </child> this i have to delete. I have to get the output result as <root> <child> <no>2</no> <name>b</name> </child> <child> <no>3</no> <name>c</name> </child> </root> ////////////////////////////// My code for this: XElement xml = XElement.Load(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml"); foreach (XElement child in xml.Elements()) { if (child.Element("no").Value.Trim().Equals("1")) { //Delete this node child.RemoveAll(); xml.Save(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml"); } } ...I could able to delete the node. but not completely. Its leaving <child/> tag. I get this output(xml file) <root> <child/> //I wants this should be deleted <child> <no>2</no> <name>b</name> </child> <child> <no>3</no> <name>c</name> </child> </root> So please suggest me how to do that. Thanks in advance
-
Hi all, I have a XML file like below <root> <child> <no>1</no> <name>a</name> </child> <child> <no>2</no> <name>b</name> </child> <child> <no>3</no> <name>c</name> </child> </root> I want to delete the paticular node(Completely, including its parent node). For example <child> <no>1</no> <name>a</name> </child> this i have to delete. I have to get the output result as <root> <child> <no>2</no> <name>b</name> </child> <child> <no>3</no> <name>c</name> </child> </root> ////////////////////////////// My code for this: XElement xml = XElement.Load(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml"); foreach (XElement child in xml.Elements()) { if (child.Element("no").Value.Trim().Equals("1")) { //Delete this node child.RemoveAll(); xml.Save(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml"); } } ...I could able to delete the node. but not completely. Its leaving <child/> tag. I get this output(xml file) <root> <child/> //I wants this should be deleted <child> <no>2</no> <name>b</name> </child> <child> <no>3</no> <name>c</name> </child> </root> So please suggest me how to do that. Thanks in advance
Try .Remove() instead. You may also want to replace the loop with a LINQ query, it will probably be faster.
XElement xml = XElement.Load(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml");
// find elements to delete: assume one
var toDelete = (from e in xml.Descendants("child")
where (from c in e.Descendants("no")
where c.Value.Trim() == "1"
select c).Count() > 0
select e).FirstOrDefault();
// if found, delete
if (toDelete != null)
{
toDelete.Remove();
}'Howard
-
Try .Remove() instead. You may also want to replace the loop with a LINQ query, it will probably be faster.
XElement xml = XElement.Load(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml");
// find elements to delete: assume one
var toDelete = (from e in xml.Descendants("child")
where (from c in e.Descendants("no")
where c.Value.Trim() == "1"
select c).Count() > 0
select e).FirstOrDefault();
// if found, delete
if (toDelete != null)
{
toDelete.Remove();
}'Howard
Thanks for your reply. I got the result. Here is code: XElement xml = XElement.Load(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml"); foreach (XElement child in xml.Elements()) { if (child.Element("no").Value.Trim().Equals("1")) { IEnumerable<XElement> c = child.DescendantsAndSelf(); //Delete this node c.Remove<XElement>(); //child.RemoveNodes(); } } xml.Save(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml"); I will also try as you told.
-
Try .Remove() instead. You may also want to replace the loop with a LINQ query, it will probably be faster.
XElement xml = XElement.Load(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml");
// find elements to delete: assume one
var toDelete = (from e in xml.Descendants("child")
where (from c in e.Descendants("no")
where c.Value.Trim() == "1"
select c).Count() > 0
select e).FirstOrDefault();
// if found, delete
if (toDelete != null)
{
toDelete.Remove();
}'Howard
I tried your logic. Its working fine. What if toDelete.Count() is more than one.(If more than one node satis fies the condition). I placed that in foreach loop tried to delete all such type of nodes. XElement xml = XElement.Load(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml");// find elements to delete: assume one var toDelete = from e in xml.Descendants("child") where (from c in e.Descendants ("no") where c.Value.Trim() == "1" select c).Count()>0 select e;// if found, delete if(toDelete.Count()>0) // If count = 2, its deleting 1. when it comes into loop again for 2nd time giving null reference exception. { foreach(var node in toDelete) { node.Remove(); } } xml.Save((@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml"); Whats the reason for that.
modified on Wednesday, August 27, 2008 8:18 AM
-
I tried your logic. Its working fine. What if toDelete.Count() is more than one.(If more than one node satis fies the condition). I placed that in foreach loop tried to delete all such type of nodes. XElement xml = XElement.Load(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml");// find elements to delete: assume one var toDelete = from e in xml.Descendants("child") where (from c in e.Descendants ("no") where c.Value.Trim() == "1" select c).Count()>0 select e;// if found, delete if(toDelete.Count()>0) // If count = 2, its deleting 1. when it comes into loop again for 2nd time giving null reference exception. { foreach(var node in toDelete) { node.Remove(); } } xml.Save((@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml"); Whats the reason for that.
modified on Wednesday, August 27, 2008 8:18 AM
Remove the .FirstOrDefault from the end of the query, you now have a list of XElements to remove.. foreach (var item in toDelete) { item.Remove(); }
'Howard
-
Remove the .FirstOrDefault from the end of the query, you now have a list of XElements to remove.. foreach (var item in toDelete) { item.Remove(); }
'Howard
Yes i did the same thing as you told. The problem is after deleting the first occured element, it is coming out from the loop or the value of toDelete is becoming null. I posted this code in my previous reply. I really surprised and i dont understand why it is not deleting remaining elements which are satisfied that condition. Thanks for your suggestions. cheers, sekhar
-
I tried your logic. Its working fine. What if toDelete.Count() is more than one.(If more than one node satis fies the condition). I placed that in foreach loop tried to delete all such type of nodes. XElement xml = XElement.Load(@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml");// find elements to delete: assume one var toDelete = from e in xml.Descendants("child") where (from c in e.Descendants ("no") where c.Value.Trim() == "1" select c).Count()>0 select e;// if found, delete if(toDelete.Count()>0) // If count = 2, its deleting 1. when it comes into loop again for 2nd time giving null reference exception. { foreach(var node in toDelete) { node.Remove(); } } xml.Save((@"D:\Other Projects\LinqtoXml\LinqtoXml\XMLFile1.xml"); Whats the reason for that.
modified on Wednesday, August 27, 2008 8:18 AM
I think it may be to do with the references being invalid after the first one is deleted. My guess is that the XElement retains a pointer or something within the parent and this becomes invalid when an earlier one is deleted. Try a do..while loop instead, deleting one at a time
var found = false;
do
{
// find one element to remove
var toDelete = (from e in xml.Descendants("child")
where (from c in e.Descendants("no")
where c.Value.Trim() == "1"
select c).Count() > 0
select e).FirstOrDefault();
found = (toDelete != null);
if (found) toDelete.Remove();
} while (found);'Howard