Solved

Create or Update XElements with XAttributes and delete them if exist

Posted on 2010-08-22
6
597 Views
Last Modified: 2013-11-11
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
0
Comment
Question by:MSFanboy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
6 Comments
 
LVL 21

Expert Comment

by:naspinski
ID: 33497482
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
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 33498108
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
 

Author Comment

by:MSFanboy
ID: 33505224
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
SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

 
LVL 63

Accepted Solution

by:
Fernando Soto earned 500 total points
ID: 33505442
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
 

Author Closing Comment

by:MSFanboy
ID: 33620678
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
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 33621403
Not a problem, as always glad to help.  ;=)

As far as  oversea personal training, EE will have to be the connection for now.
0

Featured Post

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
API v SOA 8 64
Visual Studio npm 1 39
Why use this lambda? 12 96
What is needed to become a DBA? 7 56
Flash (http://en.wikipedia.org/wiki/Adobe_Flash) has evolved over the years to where it has become a masterful tool for displaying content screen.  It has excellent layout placement, UI precision as well as rendering capabilities. This, along with t…
It seems a simple enough task, yet I see repeated questions asking how to do it: how to pass data between two forms. In this article, I will show you the different mechanisms available for you to do just that. This article is directed towards the .N…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question