简体   繁体   中英

Delete an element with specific node name from XML file using XDocument and XmlDocument class

I am trying to delete an element with specific node name. Using the following code but receive an error like "Name cannot begin with the '2' character, hexadecimal value 0x32." As I understand this method is not correct for the relevant xml format.

How can I delete Table with specific User_Name info. should delete specific table When I try to delete Administrator User

RemoveElement("Accounts.xml", "User", "Test1");

private static void RemoveElement(string xmlFile, string elementName, string elementAttribute)
    {
        XDocument xDocument = XDocument.Load(xmlFile);
        foreach (var profileElement in xDocument.Descendants("Table").ToList())              
        {
            if (profileElement.Attribute(elementAttribute).Value == elementName) 
            {
                profileElement.Remove();                               
            }
        }
        xDocument.Save(xmlFile);
    }

Here is the Xml file;

`<?xml version="1.0" encoding="utf-8"?>
<Accounts>
  <Table>
    <User>Administrator</User>
    <Domain>Localhost</Domain>
    <Password>Test</Password>
    <Account_Type>Windows</Account_Type>
 </Table>
 <Table>
    <User>Test1</User>
    <Domain>demo</Domain>
    <Password>empty</Password>
    <Account_Type>Domain</Account_Type>
 </Table>
</Accounts>`

Yeah Found it how you can delete when you get info from texBox

xDoc.Load("Accounts.xml");
                foreach (XmlNode node in xDoc.SelectNodes("Accounts/Table"))
                {
                    if (node.SelectSingleNode("User").InnerText == textBox1.Text)
                    {
                        node.ParentNode.RemoveChild(node);
                    }

                }
            xDoc.Save("Accounts.xml");

But I Want to get info from listview. I receive an error When I try to use following code.

Error : InvalidArgument=Value of '0' is not valid for 'index'.\\r\\nParameter name: index

listViewMevcutKullaniciListesi.Items.RemoveAt(listViewMevcutKullaniciListesi.SelectedIndices[0]);

xDoc.Load("Accounts.xml");
                foreach (XmlNode node in xDoc.SelectNodes("Accounts/Table"))
                {
                    if (node.SelectSingleNode("User").InnerText == listViewMevcutKullaniciListesi.SelectedIndices[0].ToString())
                    {
                        node.ParentNode.RemoveChild(node);
                    }

                }
            xDoc.Save("Accounts.xml");

Original code snippet doesn't work because name of user is not an attribute of user but a value. Also, you can replace .Descendants("Table") with .Descendants(elementName) to avoid unnecessary if statement. I think, the most elegant way to achieve needed functionality is to use Linq to Xml:

XDocument xDocument = XDocument.Load(xmlFile);

xDocument.Descendants(elementName)
    .Where(e => e.Value == elementAttribute)
    .ToList()
    .ForEach(e => e.Remove());

xDocument.Save(xmlFile);

As for your second question: I believe that you remove first element in this line

listViewMevcutKullaniciListesi.Items.RemoveAt(listViewMevcutKullaniciListesi.SelectedIndices[0]);

When you call listViewMevcutKullaniciListesi.SelectedIndices[0] for the second time you obviously get an Exception. Also, listViewMevcutKullaniciListesi.SelectedIndices[0].ToString() don't give you selected item but just it's number.

Here is the answer with XmlDocument class; You are calling the method like

`RemoveElementWithXmlDocument("Accounts.xml", "Accounts/Table", "User", listViewMevcutKullaniciListesi.SelectedItems[0].Text);`

method;

private static void RemoveElementWithXmlDocument(string xmlFile, string nodeName, string elementName, string elementAttribute)
    {
        xDoc.Load(xmlFile);
        try
        {
            foreach (XmlNode node in xDoc.SelectNodes(nodeName))
            {
                if (node.SelectSingleNode(elementName).InnerText == elementAttribute)
                {
                    node.ParentNode.RemoveChild(node);
                }
            }
            xDoc.Save(xmlFile);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

And also I wanna use XDocument class for same structure But I receive an exception like "Object reference not set to an instance of an object" in foreach loop when the ran profileElement.Remove(); line. If I comment out to this line never get the exception but I need this line for removing relevant node from xml. So, As I understand I missing something in XDocument. need your help

RemoveElementWithXDocument("Accounts.xml", "Table", "User", listViewMevcutKullaniciListesi.SelectedItems[0].Text);

method for XDocument

private static void RemoveElementWithXDocument(string xmlFile, string nodeName, string elementName, string elementAttribute)
    {
        XDocument xDocument = XDocument.Load(xmlFile);
        try
        {
            foreach (XElement profileElement in xDocument.Descendants(nodeName))
            {
                if (profileElement.Element(elementName).Value == elementAttribute)
                {
                    profileElement.Remove();
                }
            }
            xDocument.Save(xmlFile);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM