Robert W. Hunter
Robert W. Hunter

Reputation: 3003

C# Linq to XML add, update, delete

I have this code

        XElement newClient= new XElement("Client",
            new XElement("Name", cmbClient.Text),
            new XElement("Service",
                new XElement("ServName", cmbService.Text)));
        xmlDoc.Add(newClient);
        xmlDoc.Save("Settings.xml");

Which creates this

<?xml version="1.0" encoding="utf-8"?>
<Clients>
  <Client>
    <Name>Client Name</Name>
    <Services>
      <ServName>Service Name</ServName>
    </Services>
  </Client>
</Clients>

If i press again Button1, then It will create another Client section, that's OK but what I want is:

  1. Create a new Client section if it does not exists.
  2. If Client exists, then add a ServName to it, instead of replacing what already has.
  3. If a service already exists on a client, then do nothing, because already exists.

Any clue? I'm starting with linq to xml... thanks in advice!

EDIT: Solution provided by mixin answers from Dmitry Dovgopoly and Leon Newswanger thank you two! :D

XDocument xDoc = XDocument.Load("Settings.xml");
var Clients =
    from client in xDoc.Root.Elements("Client")
    where client.Element("Name").Value == cmbClient.Text
    select client;
if (Clients.Count() > 0)
{
    var Client =
        (from client in xDoc.Root.Elements("Client")
        where client.Element("Name").Value == cmbClient.Text
        select client).Single();
            if (Client.Element("Services").Elements().Count(el => el.Value == cmbService.Text) == 0)
            {
                Client.Element("Services").Add(new XElement("ServName", cmbService.Text));
            }
}
else
{
    XElement newClient = new XElement("Client",
        new XElement("Name", cmbClient.Text),
        new XElement("Services",
            new XElement("ServName", cmbService.Text)));
    xDoc.Root.Add(newClient);
}
xDoc.Save("Settings.xml");

Upvotes: 3

Views: 11222

Answers (4)

Leon Newswanger
Leon Newswanger

Reputation: 617

This is tested and working:

    XDocument xDoc = XDocument.Load("Settings.xml");
    var Clients =
        from client in xDoc.Root.Elements("Client")
        where client.Element("Name").Value == cmbClient.Text
        select client;
    if (Clients.Count() > 0)
    {
        var Client =
            (from client in xDoc.Root.Elements("Client")
            where client.Element("Name").Value == cmbClient.Text
            select client).Single();
        if (Client.Elements("Services").Count() == 0)
        {
            Client.Add(
                new XElement("Services",
                    new XElement("Service", cmbService.Text)));
        }
    }
    else
    {
        XElement newClient = new XElement("Client",
            new XElement("Name", cmbClient.Text),
            new XElement("Services",
                new XElement("ServName", cmbService.Text)));
        xDoc.Root.Add(newClient);
    }
    xDoc.Save("Settings.xml");

Note: If cmbService is null it will still create the service but as an empty tag. If you're going to use this to read and write with the possibilities of nulls you'll have to check for them at some point.

Upvotes: 1

Dmitrii Dovgopolyi
Dmitrii Dovgopolyi

Reputation: 6301

You can use XElement.Element(name) method to obtain specific element or XElement.Elements() to enumerate through all elements.

if (xmlDoc.Elements("Client").Count() == 0)
{
    //Client section does not exist. We add new section.
    XElement newClient = new XElement("Client",
        new XElement("Name", mbClient.Text),
        new XElement("Service",
    new XElement("ServName", cmbService.Text)));
    xmlDoc.Add(newClient);
}
else //Client section exists.
{
    //obtain <service> section
    XElement service = xmlDoc.Element("Client").Element("Service");

    if (service.Elements().Count(el => el.Value == cmbService.Text) == 0)
    { 
        //there is no service with name cmbService.Text. We add one.
        service.Add(new XElement("ServName", cmbService.Text));
    }
}

Upvotes: 3

chridam
chridam

Reputation: 103435

You could try:

bool checkClientElement = xmlDoc.Descendants("Client").Any();

if (!checkClientElement)
{
    XElement newClient= new XElement("Client",
         new XElement("Name", mbClient.Text),
         new XElement("Service",
         new XElement("ServName", cmbService.Text)));
    xmlDoc.Add(newClient);
    xmlDoc.Save("Settings.xml");
}

Upvotes: 1

AYK
AYK

Reputation: 3322

Not tested at all, but should work.

  System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
            xmlDoc.Load("Settings.xml");
            if (xmlDoc.SelectNodes("/Clients/Client").Count <= 0)
            {
                XElement newClient = new XElement("Client",
           new XElement("Name", cmbClient.Text),
           new XElement("Service",
               new XElement("ServName", cmbService.Text)));
                xmlDoc.Add(newClient);
                xmlDoc.Save("Settings.xml");
            }
            else
            {
                //find Service tag and add a new child element here
            }

Upvotes: 1

Related Questions