Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. LINQ
  4. Linq to XML

Linq to XML

Scheduled Pinned Locked Moved LINQ
tutorialcsharplinqxml
7 Posts 2 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    K V Sekhar
    wrote on last edited by
    #1

    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

    H 1 Reply Last reply
    0
    • K K V Sekhar

      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

      H Offline
      H Offline
      Howard Richards
      wrote on last edited by
      #2

      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

      K 2 Replies Last reply
      0
      • H Howard Richards

        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

        K Offline
        K Offline
        K V Sekhar
        wrote on last edited by
        #3

        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.

        1 Reply Last reply
        0
        • H Howard Richards

          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

          K Offline
          K Offline
          K V Sekhar
          wrote on last edited by
          #4

          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

          H 2 Replies Last reply
          0
          • K K V 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

            H Offline
            H Offline
            Howard Richards
            wrote on last edited by
            #5

            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

            K 1 Reply Last reply
            0
            • H Howard Richards

              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

              K Offline
              K Offline
              K V Sekhar
              wrote on last edited by
              #6

              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

              1 Reply Last reply
              0
              • K K V 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

                H Offline
                H Offline
                Howard Richards
                wrote on last edited by
                #7

                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

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups