Create or Update XElements with XAttributes and delete them if exist

Hello,

I really don`t like xml. Therefore I struggle with the even most easiest task. Thats annoying.


<Committees>
   <Committee Name="xxxx"  CanVote=True     Id=3 />
   <Committee Name="yyyy"  CanVote=False    Id=1 />
   <Committee Name="bbbb"  CanVote=True     Id=2 />
   <Committee Name="cccc"  CanVote=False    Id=4 />
</Committees>

Open in new window



At the beginning the file is empty with only: <Committees />

Then I have a Committee class with some properties like above in the .XML.

When I iterate the List<Committee> I want to search for every Committee.Id in

the .XML so in each <Committee ....>.

Main problem:

IF the Id is matching I want to update the CanVote = with the Committee.CanVote value. from the List.

Else the Node <Committee Name=...  ... /> must be Inserted



and... How does XLinq behave when I want to update a XElement which is not existing does it make an Insert automatically?

Fernando!!!! :P
MSFanboyAsked:
Who is Participating?
 
Fernando SotoRetiredCommented:
Hi MSFanboy;

The code was not the difficult part it was the approach that I came up with that I spent the time on. All in all about 45 minutes so I could test it as well and make sure it would run.

I am just learning WPF myself now and I hear that it has a long learning curve, well I hope not to long.

Good luck;
Fernando
0
 
naspinskiCommented:
First off, you should wrap the CanVote=False in quotes like CanVote="False"

You will just have to make a function to insert if it is not there (it is not automatic).  Something like this:
public void UpdateCommittee(XDocument xDox, int committeeId)
{
  // try to find it if it exists
  XElement committee = xDoc.Descendants("Committee")
    .Where(x => Convert.ToInt32(x.Attribute("Id").Value) == committeeId;
  // if not, make it (you will have to insert the correct values)
  if comittee == null
  {
    committee = new XElement("Comittee", 
      new XAttribute("name", "some-new-name"),
      new XAttribute("CanVote", "False"),
      new XAttribute("Id", "5"))
  }
  else //flip its vote ability
  { 
    XAttribute canVote = committee.Attribute("CanVote");
    canVote.Value = !Convert.ToBoolean(canVote.Value)
  }
}
// be sure to save it when you're done

Open in new window

0
 
Fernando SotoRetiredCommented:
Hi MSFanboy;

The code in the code snippet will read in an XML document, compare the committee class that are in the XML document and also NOT in the XML document with a list of Committee's classes to be inserted or updated.

Fernando
// Class variable
private List<Committee> lstCommittees = new List<Committee>();

// Open document
XDocument xdoc = XDocument.Load("Committees.xml");

// Get a list of Committee from the XML file
List<Committee> XmlCommittees = (from x in xdoc.Descendants("Committee")
                                 select new Committee
                                 {
                                     Name = x.Attribute("Name").Value,
                                     CanVote = x.Attribute("CanVote").Value,
                                     Id = Convert.ToInt32(x.Attribute("Id").Value)
                                 }).ToList();

// Find all Committee that are in the lstCommittees but not in the XML
List<Committee> CommitteeNotInXml = lstCommittees.Except(XmlCommittees, new CommitteeComparer()).ToList();
// Find all the Committee that are in both lsit
List<Committee> CommitteeInInXml = lstCommittees.Intersect(XmlCommittees, new CommitteeComparer()).ToList();

if (CommitteeNotInXml.Count > 0)
{
    // Insert Committee nodes
    foreach(Committee c in CommitteeNotInXml)
    {
        XElement newCommittee = new XElement("Committee",
                                    new XAttribute("Name", c.Name),
                                    new XAttribute("CanVote", c.CanVote),
                                    new XAttribute("Id", c.Id));
        xdoc.Root.Add(newCommittee);
    }
}

if (CommitteeInInXml.Count > 0)
{
    // Update Committee nodes
    foreach (Committee c in CommitteeInInXml)
    {
        XElement commit = (from node in xdoc.Descendants("Committee")
                           where node.Attribute("Id").Value == c.Id.ToString()
                           select node).FirstOrDefault();

        commit.Attribute("Name").Value = c.Name;
        commit.Attribute("CanVote").Value = c.CanVote;
    }
}

// Write XML to file if modified
if (CommitteeNotInXml.Count > 0 || CommitteeInInXml.Count > 0)
{
    xdoc.Save("CommitteesModified.xml");
}

// Support classes

public class CommitteeComparer : IEqualityComparer<Committee>
{

    bool IEqualityComparer<Committee>.Equals(Committee CommitteeA, Committee CommitteeB)
    {
        if( CommitteeA == null ) return false;
        if( CommitteeB == null ) return false;
        if (CommitteeA.Id == CommitteeB.Id)
            return true;
        else
            return false;
    }

    int IEqualityComparer<Committee>.GetHashCode(Committee objCommittee)
    {
        return objCommittee.Id.GetHashCode();
    }
}

public class Committee
{
    public String Name { get; set; }
    public string CanVote { get; set; }
    public int Id { get; set; }
}

Open in new window

0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
MSFanboyAuthor Commented:
Wooooaaaaahhhhhhhh.... Fernando is back in town and rides over naspinski XD

One day I gotta learn XLinq :P  so busy with EF + wpf...

I will return here in about 2 days. Gotta check that code tomorrow.

Nice you are still alive and kicking :D

Tell me Fernando, how much time did you need for that code?
0
 
MSFanboyAuthor Commented:
Hello Fernando,

sorry for replying so late. I was on holidays... and some days later I remembered my question here.

Judging my question your code was very good therefore I marked it as A with Yes,Yes,Yes.

In fact I had to change my concept but could use some of your stuff :) Above all I have learned some new stuff.

Thanks again for the fast help. Are you ready now for oversea personal training? :P
0
 
Fernando SotoRetiredCommented:
Not a problem, as always glad to help.  ;=)

As far as  oversea personal training, EE will have to be the connection for now.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.