1

I'm having trouble trying to update my xml file with a new value. I have a class Person, which only contains 2 strings, name and description. I populate this list and write it as an XML file. Then I populate a new list, which contains many of the same names, but some of them contains descriptions that the other list did not contain. How can I check if the name in the current XML file contains a value other than "no description", which is the default for "nothing"?

Part of the xml file:

<?xml version="1.0" encoding="utf-8"?>
<Names>
  <Person ID="2">
    <Name>Aaron</Name>
    <Description>No description</Description>
  </Person>
  <Person ID="2">
    <Name>Abdi</Name>
    <Description>No description</Description>
  </Person>
</Names>

And this is the method for writing the list to the xml file:

public static void SaveAllNames(List<Person> names)
{
    XDocument data = XDocument.Load(@"xml\boys\Names.xml");   

    foreach (Person person in names)
    {
        XElement newPerson = new XElement("Person",
                                 new XElement("Name", person.Name),
                                 new XElement("Description", person.Description)
                             );

        newPerson.SetAttributeValue("ID", GetNextAvailableID());

        data.Element("Names").Add(newPerson);
    }
    data.Save(@"xml\boys\Names.xml");
}

In the foreach loop how do I check if the person's name is already there, and then check if the description is something other than "no description", and if it is, update it with the new information?

Ahmad Mageed
  • 94,561
  • 19
  • 163
  • 174
Svein Erik
  • 531
  • 2
  • 11
  • 24

3 Answers3

2

I'm not sure I understand properly what you want, but I'm assuming you want to update the description only when the name is already there and the description is currently No description (which you should probably change to an empty string, BTW).

You could put all the Persons into a Dictionary based by name:

var doc = …;

var persons = doc.Root.Elements()
                      .ToDictionary(x => (string)x.Element("Name"), x => x);

and then query it:

if (persons.ContainsKey(name))
{
    var description = persons[name].Element("Description");
    if (description.Value == "No description")
        description.Value = newDescription;
}

That is, if you care about performance. If you don't, you don't need the dictionary:

var person = doc.Root.Elements("Person")
                     .SingleOrDefault(x => (string)x.Element("Name") == name);

if (person != null)
{
    var description = person.Element("Description");
    if (description.Value == "No description")
        description.Value = newDescription;
}
svick
  • 236,525
  • 50
  • 385
  • 514
0

You can use the Nodes-Method on XElement and check manually.

But i will advise you to use the XPathEvaluate-Extension Method

For XPath expression take a look at: How to check if an element exists in the xml using xpath?

Community
  • 1
  • 1
Larry
  • 487
  • 4
  • 8
0

I think you could create a peoplelist which only contains people not in the xml.

like ↓

        var containlist = (from p in data.Descendants("Name") select p.Value).ToList();
        var result = (from p in peoplelist where !containlist.Contains(p.Name) select p).ToList();

so that , you would no need to change anything with your exist method ...

just call it after..

SaveAllNames(result); 
shenhengbin
  • 4,236
  • 1
  • 24
  • 33