Mariusz
Mariusz

Reputation: 55

How to change a value inside XML file using c# Visual Studio

I am trying to change values inside XML file. This is my XML "person.xml" file:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Table>
  <Person>
    <Number>1</Number>
    <Name>Mariano</Name>
    <Last Name>Italiano</Last Name>
    <Age>36</Age>
  </Person>
  <Person>
    <Number>2</Number>
    <Name>John</Name>
    <Last Name>Smith</Last Name>
    <Age>32</Age>
  </Person>
  <Person>
    <Number>3</Number>
    <Name>Bob</Name>
    <Last Name>Leckie</Last Name>
    <Age>50</Age>
  </Person>
  <Person>
    <Number>4</Number>
    <Name>Patrick</Name>
    <Last Name>Collins</Last Name>
    <Age>63</Age>
  </Person>
</Table>

And i want my program to do some things:

  1. Find a name written in textBox2->Text. Then if the name exists i want to change it to name written in textBox3->Text.

  2. Remove (if found) whole Person if CheckBoxDelete is set to true

I know how to create such a XML file (found an example somewhere) but i can't find a solution how to find and remove if neccessary.

I am using Visual Studio 2015 if it matters.

Thank You.

Upvotes: 0

Views: 2048

Answers (3)

Jack J Jun- MSFT
Jack J Jun- MSFT

Reputation: 5986

You can use XDocument to replace the value and delete the person according to the Name.

Code:

 public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    public string filename = "D:\\test.xml";
    private void BtnRePlace_Click(object sender, EventArgs e)
    {
        XDocument doc = XDocument.Load(filename);
        doc.Descendants("Person").Descendants("Name").Where(i => i.Value == txtReplaceFirstName.Text).FirstOrDefault().SetValue(txtReplaceLastName.Text);
        doc.Save(filename);
    }

    private void btndelete_Click(object sender, EventArgs e)
    {
        XDocument doc = XDocument.Load(filename);
        doc.Descendants("Person").Where(i => i.Element("Name").Value == txtReplaceFirstName.Text&& i.Element("LastName").Value == txtReplaceLastName.Text).FirstOrDefault().Remove();
        doc.Save(filename);
    }
}

Besides, your xml file have an error, the Last Name should be LastName without space.

Upvotes: 1

William Walseth
William Walseth

Reputation: 2923

XML is the object, so consider re-using existing objects before creating more POCOs.

Here's code that shows how to find, delete, and update elements in XML. Take some time to learn XPath, it's very powerful, flexible, and available across nearly every platform.

using System;
using System.Threading.Tasks;
using System.Xml;

namespace testconsole
{
        class Program
        {
                public static string strFileName = "c:\\temp\\test.xml";
                static void Main(string[] args) {
                        XmlDocument xml = new XmlDocument();
                        xml.Load(strFileName);

                        string strMatchName = "Mariano";
                        string strXPath = "/Table/Person[Name='" + strMatchName + "']";
                        XmlElement ndPerson = (XmlElement)xml.SelectSingleNode(strXPath);

                        if (ndPerson != null) {
                            // Delete if the person is found
                            ndPerson.ParentNode.RemoveChild(ndPerson);
                        }

                        string strNewName = "Bob";
                        strXPath = "/Table/Person/Name[.='" + strNewName + "']";
                        XmlElement ndName = (XmlElement)xml.SelectSingleNode(strXPath);
                        if (ndName != null) {
                            ndName.InnerText = "Robert"; // new name
                        }

                        xml.Save(strFileName);
                }
        }
}

Upvotes: 0

flipflop
flipflop

Reputation: 103

You could map (i.e. deserialize) the data to POCO objects, manipulate the data and serialize again. Might be a bit overkill though. As others stated, using XDocument might be good enough.

Here is a minimal example:

public class Person
{
    [XmlElement]
    public int Number { get; set; }
    [XmlElement]
    public string Name { get; set; }
    [XmlElement]
    public string LastName { get; set; }
    [XmlElement]
    public int Age { get; set; }
    public override string ToString() => $"{Name} {LastName} is {Age}";
}

[XmlRoot("Table")]
public class RootObject
{
    [XmlElement("Person")]
    public List<Person> Persons;
}

class Program
{
    static void Main(string[] args)
    {
        var xmlSer = new XmlSerializer(typeof(RootObject));
        using var fs = new FileStream("input.xml", FileMode.Open);
        var doc = (RootObject)xmlSer.Deserialize(fs);

        foreach (var p in doc.Persons)
        {
            System.Console.WriteLine(p);
        }
        // do whatever with the RootObject instance            
    }
}

Upvotes: 0

Related Questions