3

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");
Robert W. Hunter
  • 2,895
  • 7
  • 35
  • 73

4 Answers4

3

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));
    }
}
Dmitrii Dovgopolyi
  • 6,231
  • 2
  • 27
  • 44
1

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
            }
AYK
  • 3,312
  • 1
  • 17
  • 30
1

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");
}
chridam
  • 100,957
  • 23
  • 236
  • 235
  • This only checks if any child elements exists and if there are none it adds. If there are any existing clients this won't add any. It also won't modify an existing client. – Leon Newswanger Nov 08 '12 at 18:05
1

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.

Leon Newswanger
  • 617
  • 1
  • 5
  • 17
  • @DmitryDovgopoly I realize this but from the context of the question it would make more sense to open it as an XDocument since the contents come directly from a file. – Leon Newswanger Nov 09 '12 at 07:04
  • It isn't working, it creates a new client and a new service if it doesn't exist, but if I try to add another service to my client, nothing hapens... – Robert W. Hunter Nov 09 '12 at 15:12
  • @user1381537 I'm sorry I must have misunderstand the question. I was under the assumption that there was only one service per client. Let me make sure I understand your goal before I make modifications. If a client exists and the service does not, you wish to add the service. If the client exists and so does the service for that client, do nothing because it exists. If the client doesn't exist, add a new client entry. Is this correct? – Leon Newswanger Nov 09 '12 at 15:52