views:

8069

answers:

3

Hello!

If got 2 Questions:

1. I've sarted working around with Linq to XML and i'm wondering if it is possible to change a XML document via Linq. I mean, is there someting like

XDocument xmlDoc = XDocument.Load("sample.xml");

update item in xmlDoc.Descendants("item")
where (int)item .Attribute("id") == id
...

2. I already know how to create and add a new XMLElement by simply using

xmlDoc.Element("items").Add(new XElement(......);

but how can i remove a single entry.

XML sample data:

<items>
  <item id="1" name="sample1" info="sample1 info" web="" />
  <item id="2" name="sample2" info="sample2 info" web="" />
</itmes>
+5  A: 

Is this what you have in mind?

using System;
using System.Linq;
using System.Xml.Linq;

static void Main(string[] args)
{
    string xml = @"<data><record id='1'/><record id='2'/><record id='3'/></data>";
    StringReader sr = new StringReader(xml);
    XDocument d = XDocument.Load(sr);

    // the verbose way, if you will be removing many elements (though in
    // this case, we're only removing one)
    var list = from XElement e in d.Descendants("record")
               where e.Attribute("id").Value == "2" 
               select e;

    // convert the list to an array so that we're not modifying the
    // collection that we're iterating over
    foreach (XElement e in list.ToArray())
    {
       e.Remove();
    }

    // the concise way, which only works if you're removing a single element
    // (and will blow up if the element isn't found)
    d.Descendants("record").Where(x => x.Attribute("id").Value == "3").Single().Remove();

    XmlWriter xw = XmlWriter.Create(Console.Out);
    d.WriteTo(xw);
    xw.Flush();
    Console.ReadLine();
}
Robert Rossney
@Robert, what must we include in the code there to ensure that it doesn't blow up? thanks.
melaos
That's what the verbose way above the concise way is for: if you build the list and then iterate over it, the code will work if the list is empty.
Robert Rossney
+2  A: 

thank you for your answer. everything works fine.

just as completition to my questions the code below shows how to modify a single entry:

string xml = @"<data><record id='1' info='sample Info'/><record id='2' info='sample Info'/><record id='3' info='sample Info'/></data>";
StringReader sr = new StringReader(xml);
XDocument d = XDocument.Load(sr);


d.Descendants("record").Where(x => x.Attribute("id").Value == "2").Single().SetAttributeValue("info", "new sample info");
A: 
using System;

using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Xml.Linq;

namespace LinqToXmlTest { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) {

    }
    protected void ReadXml()
    {
        XDocument xdocument = XDocument.Load(Server.MapPath("People.xml"));
        var persons = from person in xdocument.Descendants("Person")
                      select new
                      {
                          Name = person.Element("Name").Value,
                          City = person.Element("City").Value,
                          Age = person.Element("Age").Value
                      };
        litResults.Text = "";
        foreach (var person in persons)
        {
            litResults.Text = litResults.Text + "Name: " + person.Name + "<br/>";
            litResults.Text = litResults.Text + "City: " + person.City + "<br/>";
            litResults.Text = litResults.Text + "Age: " + person.Age + "<br/><br/>";
        }
        if (litResults.Text == "")
            litResults.Text = "No Results...";
    }

    protected void butAdd_Click(object sender, EventArgs e)
    {
        try
        {
            if (txtName.Text == "" || txtCity.Text == "" || txtAge.Text == "")
            {
                lblStatus.ForeColor = System.Drawing.Color.Red;
                lblStatus.Text = "Please Complete the form";
            }
            else
            {
                XDocument xdocumnet = XDocument.Load(Server.MapPath("People.xml"));
                xdocumnet.Element("Persons").Add(new XElement("Person",
                    new XElement("Name", txtName.Text),
                    new XElement("City", txtCity.Text),
                    new XElement("Age", txtAge.Text)));
                xdocumnet.Save(Server.MapPath("People.xml"));
                lblStatus.ForeColor = System.Drawing.Color.Green;
                lblStatus.Text = "Data Successfully loaded to xml file";
                txtName.Text = "";
                txtCity.Text = "";
                txtAge.Text = "";
                ReadXml();
            }
        }
        catch
        {
            lblStatus.ForeColor = System.Drawing.Color.Red;
            lblStatus.Text = "Sorry unable to precess request.Please try again";
        }


    }

    protected void butRead_Click(object sender, EventArgs e)
    {
        ReadXml();
        lblStatus.Text = "";
    }

    protected void btnUpdate_Click(object sender, EventArgs e)
    {
        try
        {
            if (txtName.Text == "" || txtCity.Text == "" || txtAge.Text == "")
            {
                lblStatus.ForeColor = System.Drawing.Color.Red;
                lblStatus.Text = "Please enter all details in the form";
            }
            else
            {
                XDocument xdocument = XDocument.Load(Server.MapPath("People.xml"));
                var persondata = (from person in xdocument.Descendants("Person")
                                  where person.Element("Name").Value.Equals(txtName.Text)
                                  select person).Single();


                persondata.Element("City").Value = txtCity.Text;
                persondata.Element("Age").Value = txtAge.Text;

                xdocument.Save(Server.MapPath("People.xml"));
                lblStatus.ForeColor = System.Drawing.Color.Green;
                lblStatus.Text = "The data updated successfully";
                ReadXml();
            }
        }
        catch(Exception ex)
        {
            lblStatus.ForeColor = System.Drawing.Color.Red;
            lblStatus.Text = ex.Message;
        }
    }

    protected void btnDelete_Click(object sender, EventArgs e)
    {
        try
        {
            if (txtName.Text == "")
            {
                lblStatus.ForeColor = System.Drawing.Color.Red;
                lblStatus.Text = "Please enter the name of the person to delete...";                    
            }
            else
            {
                XDocument xdocument = XDocument.Load(Server.MapPath("People.xml"));
                var persondata = (from person in xdocument.Descendants("Person")
                                  where person.Element("Name").Value.Equals(txtName.Text)
                                  select person).Single();


                persondata.Remove();
                xdocument.Save(Server.MapPath("People.xml"));
                lblStatus.ForeColor = System.Drawing.Color.Green;
                lblStatus.Text = "The data deleted successfully...";
                txtName.Text = "";
                txtCity.Text = "";
                txtAge.Text = "";
                ReadXml();
            }
        }
        catch (Exception ex)
        {
            lblStatus.ForeColor = System.Drawing.Color.Red;
            lblStatus.Text = ex.Message;
        }
    }
}

}

Ajay JIlakara
Just slapping a block of code in doesn't really help people, especially as a lot of the code isn't related to the actual question
SteveC