0

I am trying to delete just the XML element <Contact> Where the ID matches the lstBox Selected Index. The code runs, however, it actually deletes everything inside my XML file, so I am left with an empty txt file. I have code like this:

private async void btnDeleteContact_Click(object sender, RoutedEventArgs e)
    {
        StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("Contacts.xml");
        XDocument xdoc = XDocument.Load(file.Path);
        if (lstBox.SelectedIndex != -1)
        {
            xdoc.Element("Contacts")
                .Elements("Contact")
                .Where(x => (string)x.Attribute("ID") == lstBox.SelectedItem.ToString()).Remove();
            lstBox.SelectedIndex = -1; 
            updateXMLFile(xdoc);
        }
    }

This is my XML file

<?xml version="1.0" encoding="UTF-8" ?>
<Contacts>
    <Contact>
        <ID>salpea</ID>
        <FirstName>Sally</FirstName>
        <LastName>Pearson</LastName>
        <Mobile>0431529562</Mobile>
        <Email>sallyp@hotmail.com</Email>
    </Contact>
    <Contact>
        <ID>gresul</ID>
        <FirstName>Greg</FirstName>
    <LastName>Sullivan</LastName>
        <Mobile>0432928381</Mobile>
        <Email>gregsul@outlook.com</Email>
    </Contact>
    <Contact>
        <ID>chrmac</ID>
        <FirstName>Christie</FirstName>
    <LastName>Mack</LastName>
        <Mobile>0421231231</Mobile>
        <Email>christiemack@gmail.com</Email>
    </Contact>
</Contacts>

The list box selection is in blue.

enter image description here

Not sure if it is relevant but this is my pastebin for the entire file here

Thanks for any help regarding the matter.

Rick1990
  • 95
  • 12
  • are you using c#? – Iswar Jul 15 '17 at 05:15
  • 1
    In your XML file, `...` is an *XML element* not an *XML attribute* so `(string)x.Attribute("ID") == lstBox.SelectedItem.ToString()` will always be false. And, in fact, in testing it seems nothing is removed. So I suspect the problem is actually in `updateXMLFile(xdoc);`. Can you share that code? – dbc Jul 15 '17 at 05:21
  • 1
    Demo fiddle showing nothing is removed when trying to remove the element with ID `"chrmac"`: https://dotnetfiddle.net/T6ffsH – dbc Jul 15 '17 at 05:25
  • Hi thanks for the response. The whole code is here https://pastebin.com/ftjtie8A – Rick1990 Jul 15 '17 at 05:39
  • 1
    In `updateXMLFile()` you catch and swallow all exceptions. Rather than doing that, report or log them! If somehow `FileIO.WriteTextAsync(file, xdoc.ToString());` were throwing an exception then the result might be an incomplete file. – dbc Jul 15 '17 at 05:41
  • hmm you seem to be right, I added this line Debug.WriteLine(xdoc.ToString()); At the very start of the UpdateXMLFile and it just had the whole xml file there, nothing was deleted. I am confused by what you mean about catching errors though. It seems there is no exception however when it executes the code inside the Try scope is deletes all the contents of the xml file. – Rick1990 Jul 15 '17 at 05:52
  • I got it working. I posted the answer below. – Rick1990 Jul 15 '17 at 05:59

3 Answers3

1
private async void btnDeleteContact_Click(object sender, RoutedEventArgs e)
    {
        StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("Contacts.xml");
        XDocument xdoc = XDocument.Load(file.Path);
        if (lstBox.SelectedIndex != -1)
        {
            var id = lstBox.SelectedItem.ToString();
            XmlNode node = xdoc.SelectSingleNode(string.Format("/Contacts/Contact[@ID='{0}']", id));

            if (node != null)
            {
                XmlNode parent = node.ParentNode;
                parent.RemoveChild(node);
                updateXMLFile(xdoc);
            }
        }
    }
Sushil Mate
  • 583
  • 6
  • 14
  • Hi I just tried this however it keeps saying XDocument does not contain the value SelectSingleNode. I tried to add a reference but that also did not work. – Rick1990 Jul 15 '17 at 05:52
  • Does https://stackoverflow.com/questions/35089399/selectsinglenode-is-giving-compilation-error-in-dnx-core-5-0 help? – mjwills Jul 15 '17 at 22:53
1

However, you can use xmlNode. I have gone through similar requirement and fixed by using xmlNode like this

 XmlTextReader reader = new XmlTextReader(path);

    XmlDocument doc = new XmlDocument();
    XmlNode node = doc.ReadNode(reader);

    foreach (XmlNode chldNode in node.ChildNodes)
    {
        string employeeName = chldNode.Attributes["Name"].Value;
        if (employeeName == Employee)
        {                    
            //******your code here
        }
    }

Dummy XML

 <Root>
    <Employee Name ="TestName">
    <Childs/>
 </Root>

I have taken reference from here. In your context you can just delete the child node if matched.

hope it helps you.

Iswar
  • 2,211
  • 11
  • 40
  • 65
1

I took answers from all of you and this ended up working.

private async void updateXMLFile(XDocument xdoc)
        {
            try
            {
                //StorageFile file = await installedLocation.CreateFileAsync("Contacts.xml", CreationCollisionOption.ReplaceExisting);
                StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("Contacts.xml"); //This line was the replacement for the one above.
                await FileIO.WriteTextAsync(file, xdoc.ToString());
            }
            catch (Exception ex)
            {
                String s = ex.ToString();
            }
        }

Also changed from x.Attribute to x.Element

thanks to all those who helped.

Rick1990
  • 95
  • 12