0

I am making a program that takes information from the user and saves it as an XML file. The information includes a name, and other details. I would like to be able to allow the user to enter the same name, and instead of a new element being created with the same name, it would overwrite the existing element with the new values entered.

I hope that made sense, but in case not an example would be if I entered the name John Smith, and age 250. Clearly I would like to change the typo, so I would do it again to enter John Smith, age 25. When I do this a new element is created to add another John Smith, is there a way to just edit/overwrite the existing element? I'll post the code I use to create the XML if it is any help!

Thanks in advance!

XDocument Xdoc = new XDocument(new XElement("XMLFile"));
        if (System.IO.File.Exists(filepath))
        {
            Xdoc = XDocument.Load(filepath);
        }
        else
        {
            Xdoc = new XDocument();
        }

        XElement xml = new XElement("Member");
        xml.Add(new XElement("Name", txtName.Text));
        xml.Add(new XElement("Age", txtAge.Text));
        xml.Add(new XElement("Nationality", txtNationality.Text));
        xml.Add(new XElement("EmailAddress", txtEmailAddress.Text));
        xml.Add(new XElement("ContactNumber", txtContactNumber.Text));


        if (Xdoc.Descendants().Count() > 0)
        {
            Xdoc.Descendants().First().Add(xml);
        }
        else
        {
            Xdoc.Add(xml);
        }

        Xdoc.Save(filepath);

3 Answers 3

1

You can retrieve the elements you want and set their value using their .Value property.

Note that there is a large bug in your code. When the document is initially empty, you add the first Member as the root element of your document, but after that, you add all the additional Members as children of that first member.

Here is the correct code to do the update and also add new members correctly.

XDocument Xdoc;

if (System.IO.File.Exists(filepath))
{
    Xdoc = XDocument.Load(filepath);
}
else
{
    Xdoc = new XDocument(new XElement("Members"));
}

XElement member = Xdoc
    .Descendants("Member")
    .FirstOrDefault(m => (string) m.Element("Name") == name);

if (member != null)
{
    member.Element("Age").Value = age;
    member.Element("Nationality").Value = age;
    member.Element("EmailAddress").Value = age;
    member.Element("ContactNumber").Value = age;
}
else
{
    XElement newMember = new XElement("Member",
        new XElement("Name", name),
        new XElement("Age", age),
        new XElement("Nationality", nationality),
        new XElement("EmailAddress", email),
        new XElement("ContactNumber", contactNumber)
        );

    Xdoc.Descendants("Members").First().Add(newMember);
}

Xdoc.Save(filepath);
Sign up to request clarification or add additional context in comments.

Comments

0

Sure there is. When you load your xml, create two divergent paths of action based on whether that name exists, then merge the paths back at saving the xml:

XDocument Xdoc = new XDocument(new XElement("XMLFile"));
if (System.IO.File.Exists(filepath))
{
     Xdoc = XDocument.Load(filepath);
}
else
{
     Xdoc = new XDocument();
}

var existing = Xdoc.Descendants("Member").FirstOrDefault(m => m.Element("Name")?.Value == txtName.Text);

if (existing != null) //name existed in xml
{
      existing.Element("Age").Value = txtAge.Text;
      //....
      //....
}
else
{
      XElement xml = new XElement("Member");
      xml.Add(new XElement("Name", txtName.Text));
      xml.Add(new XElement("Age", txtAge.Text));
      xml.Add(new XElement("Nationality", txtNationality.Text));
      xml.Add(new XElement("EmailAddress", txtEmailAddress.Text));
      xml.Add(new XElement("ContactNumber", txtContactNumber.Text));

      if (Xdoc.Descendants().Count() > 0)
      {
          Xdoc.Descendants().First().Add(xml);
      }
      else
      {
          Xdoc.Add(xml);
      }
}

Xdoc.Save(filepath));

Comments

0

Use XElement.SetElementValue(element, value).

Example:

xml.SetElementValue("Age", 25);

Another way you could go about this, which sounds like an overkill in this case is this: How about storing the elements names and their values in a HashMap first, and then iterating through the HashMap and creating the XML elements. And reverse the process when someone is editing a value. So whenever someone makes an edit, you dump your elements in a HashMap, update your element value, and then recreate the xml elements.

1 Comment

I was looking for the values to be entered through a text box, sorry I should have mentioned that. I have it sorted now though, thanks anyway! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.