简体   繁体   中英

Linq to XML - update/alter the nodes of an XML Document

I've got 2 Questions:

1. I've sarted working around with Linq to XML and i'm wondering if it is possible to change an 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>

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");

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();
}

The answers are in this thread...you just have to do a lot of sorting to find them, so I've done the work of compliling them for you:

  1. YES you can edit elements
  2. Deleting elements is easy: element.Remove(); (Remember to save the xDocument after that)

Now if you're reading this thread, you probably want to know HOW to edit elements. There are two different ways that data is stored in xml, eg:

<tagName attributeName="some value">another value</tagName>
  1. As an ATTRIBUTE on a tag
  2. As the content (read value) of the tag

To edit the value of an attribute , knox answered his own question:

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

In other words, get the XElement that you want to alter, and call element.SetAttributeValue("AttributeName", "new value for the attribute")

if you want to edit the value or contents of a tag, then Ajay answered it (if you dig through all his code):

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

Or, in other words, once you have the XElement you're after, just use .Value and assign away.

Remember that after you perform any of these modifications on the elements in memory, you've got to call .Save() on the XDocument if you want to persist those changes to disk.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; //using System.Xml;

namespace XMLtoLinqApp { class Program { static void Main(string[] args) {

        //XmlDocument doc = new XmlDocument();
        //XmlElement newBook=doc.CreateElement("BookParticipant");
        //newBook.SetAttribute("Author");

        //Using Functional Construction to Create an XML Schema
        XElement xBookParticipant = new XElement("BookParticipant",
                                        new XElement("FirstName", "Joe"),
                                        new XElement("LastName", "Rattz"));
        Console.WriteLine(xBookParticipant.ToString());


        //Creates the Same XML Tree as Listing 6-1 but with Far Less Code
        XElement xBookParticipants = new XElement("BookParticipants",
                                        new XElement("BookParticipant",
                                        new XAttribute("type", "Author"),
                                        new XElement("FirstName", "Joe"),
                                        new XElement("LastName", "Rattz")),
                                        new XElement("BookParticipant",
                                        new XAttribute("type", "Editor"),
                                        new XElement("FirstName", "Ewan"),
                                        new XElement("LastName", "Buckingham")));
        Console.WriteLine(xBookParticipants.ToString());


        //-- Disadvatages of XML document
        //System.Xml.XmlElement xmlBookParticipant = new System.Xml.XmlElement("BookParticipant");
        XElement xeBookParticipant = new XElement("BookParticipant");


        XDocument xDocument = new XDocument(new XElement("BookParticipants",
                                            new XElement("BookParticipant",
                                            new XAttribute("type", "Author"),
                                            new XElement("FirstName", "Joe"),
                                            new XElement("LastName", "Rattz"))));
        Console.WriteLine(xDocument.ToString());


        //--Calling the ToString Method on an Element Produces the XML Tree
        XElement name = new XElement("Name", "Joe");
        Console.WriteLine(name.ToString());

        //--Console.WriteLine Implicitly Calling the ToString Method on an Element to Produce an XML Tree


        XElement name1 = new XElement("Person",
                                      new XElement("FirstName", "Joe"),
                                      new XElement("LastName", "Rattz"));
        Console.WriteLine(name1);

        //-- Casting an Element to Its Value’s Data Type Outputs the Value
        Console.WriteLine(name);
        Console.WriteLine((string)name);

        //--Different Node Value Types Retrieved via Casting to the Node Value’s Type
        XElement count = new XElement("Count", 12);
        Console.WriteLine(count);
        Console.WriteLine((int)count);

        XElement smoker = new XElement("Smoker", false);
        Console.WriteLine(smoker);
        Console.WriteLine((bool)smoker);

        XElement pi = new XElement("Pi", 3.1415926535);
        Console.WriteLine(pi);
        Console.WriteLine((double)pi);


        DeferredQryProblem();


        GenerateXMlFromLinqQry();

        WithoutReaching();

        Ancestors();


        AncestorsAndSelf();

        SortSample();

        FindElementwithSpecificChild();

    }

    private static void DeferredQryProblem()
    {
        XDocument xDocument = new XDocument(
                    new XElement("BookParticipants",
                    new XElement("BookParticipant",
                    new XAttribute("type", "Author"),
                    new XElement("FirstName", "Joe"),
                    new XElement("LastName", "Rattz")),
                    new XElement("BookParticipant",
                    new XAttribute("type", "Editor"),
                    new XElement("FirstName", "Ewan"),
                    new XElement("LastName", "Buckingham"))));
        IEnumerable<XElement> elements =
        xDocument.Element("BookParticipants").Elements("BookParticipant");
        foreach (XElement element in elements)
        {
            Console.WriteLine("Source element: {0} : value = {1}",
            element.Name, element.Value);
        }
        foreach (XElement element in elements)
        {
            Console.WriteLine("Removing {0} = {1} ...", element.Name, element.Value);
            element.Remove();
        }
        Console.WriteLine(xDocument);


        foreach (XElement element in elements)
        {
            Console.WriteLine("Source element: {0} : value = {1}",
            element.Name, element.Value);
        }
        foreach (XElement element in elements.ToArray())
        {
            Console.WriteLine("Removing {0} = {1} ...", element.Name, element.Value);
            element.Remove();
        }
        Console.WriteLine(xDocument);
    }

    //-- Creating an Attribute and Adding It to Its Element
    private static void CreatingAttribute()
    {
        XElement xBookParticipant = new XElement("BookParticipant", new XAttribute("type", "Author"));
        Console.WriteLine(xBookParticipant);
    }

    //--Creating a Comment with Functional Construction
    private static void CreatingComment()
    {
        XElement xBookParticipant = new XElement("BookParticipant",
                                                  new XComment("This person is retired."));
        Console.WriteLine(xBookParticipant);
    }

    //--Creating a Declaration with Functional Construction
    private static void CreateXmlDeclaration()
    {
        XDocument xDocument = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"),

new XElement("BookParticipant")); Console.WriteLine(xDocument); }

    private static void GenerateXMlFromLinqQry()
    {
        BookParticipant[] bookParticipants = new[] {new BookParticipant {FirstName = "Joe", LastName = "Rattz",
                                                    ParticipantType = ParticipantTypes.Author},
                                                    new BookParticipant {FirstName = "Ewan", LastName = "Buckingham",
                                                    ParticipantType = ParticipantTypes.Editor}
                                                    };
        XElement xBookParticipants =
        new XElement("BookParticipants",
                     bookParticipants.Select(p =>
                new XElement("BookParticipant",
                new XAttribute("type", p.ParticipantType),
                new XElement("FirstName", p.FirstName),
                new XElement("LastName", p.LastName))));


        Console.WriteLine(xBookParticipants);
    }

    //-- Obtaining Elements Without Reaching
    private static void WithoutReaching()
    {
        XDocument xDocument = new XDocument(new XElement("BookParticipants",
                                            new XElement("BookParticipant",
                                            new XAttribute("type", "Author"),
                                            new XElement("FirstName", "Joe"),
                                            new XElement("LastName", "Rattz")),
                                            new XElement("BookParticipant",
                                            new XAttribute("type", "Editor"),
                                            new XElement("FirstName", "Ewan"),
                                            new XElement("LastName", "Buckingham"))));

        //-- Simple Descendants
        IEnumerable<XElement> elements = xDocument.Descendants("BookParticipant");


        foreach (XElement element in elements)
        {
            Console.WriteLine("Element: {0} : value = {1}",
            element.Name, element.Value);
        }


        //-- Descendants with Where Clause
        IEnumerable<XElement> elements1 = xDocument.Descendants("BookParticipant")
                                                   .Where(e => ((string)e.Element("FirstName")) == "Ewan");
        foreach (XElement element1 in elements1)
        {
            Console.WriteLine("Element: {0} : value = {1}",
            element1.Name, element1.Value);
        }

    }


    //-- Ancestors Prototype
    private static void Ancestors()
    {
        XDocument xDocument = new XDocument(new XElement("BookParticipants",
                                            new XElement("BookParticipant",
                                            new XAttribute("type", "Author"),
                                            new XElement("FirstName", "Joe"),
                                            new XElement("LastName", "Rattz")),
                                            new XElement("BookParticipant",
                                            new XAttribute("type", "Editor"),
                                            new XElement("FirstName", "Ewan"),
                                            new XElement("LastName", "Buckingham"))));

        IEnumerable<XElement> elements = xDocument.Element("BookParticipants").Descendants("FirstName");
        // First, I will display the source elements.
        foreach (XElement element in elements)
        {
            Console.WriteLine("Source element: {0} : value = {1}",
            element.Name, element.Value);
        }
        // Now, I will display the ancestor elements for each source element.
        foreach (XElement element in elements.Ancestors())
        {
            Console.WriteLine("Ancestor element: {0}", element.Name);
        }


        // Now, I will display the ancestor elements for each source element.
        foreach (XElement element in elements.Ancestors("BookParticipant"))
        {
            Console.WriteLine("Ancestor element: {0}", element.Name);
        }

    }


    //-- AncestorsAndSelf
    private static void AncestorsAndSelf()
    {
        XDocument xDocument = new XDocument(
            new XElement("BookParticipants",
            new XElement("BookParticipant",
            new XAttribute("type", "Author"),
            new XElement("FirstName", "Joe"),
            new XElement("LastName", "Rattz")),
            new XElement("BookParticipant",
            new XAttribute("type", "Editor"),
            new XElement("FirstName", "Ewan"),
            new XElement("LastName", "Buckingham"))));
        IEnumerable<XElement> elements =
        xDocument.Element("BookParticipants").Descendants("FirstName");
        // First, I will display the source elements.
        foreach (XElement element in elements)
        {
            Console.WriteLine("Source element: {0} : value = {1}",
            element.Name, element.Value);
        }
        // Now, I will display the ancestor elements for each source element.
        foreach (XElement element in elements.AncestorsAndSelf())
        {
            Console.WriteLine("Ancestor element: {0}", element.Name);
        }


        // Now, I will display the ancestor elements for each source element.
        foreach (XElement element in elements.AncestorsAndSelf("BookParticipant"))
        {
            Console.WriteLine("Ancestor element: {0}", element.Name);
        }

    }


    //-- Sort Smaple

    private static void SortSample()
    {
        XElement root = XElement.Load("Data.xml");
        IEnumerable<decimal> prices =
            from el in root.Elements("Data")
            let price = (decimal)el.Element("Price")
            orderby price
            select price;
        foreach (decimal el in prices)
            Console.WriteLine(el);
    }

    //-- Find an Element with a Specific Child 
    private static void FindElementwithSpecificChild()
    {
        XElement root = XElement.Load("data.xml");
        IEnumerable<XElement> tests =
            from el in root.Elements("Data")
            where (int)el.Element("Quantity") > 3
            select el;
        foreach (XElement el in tests)
            Console.WriteLine((string)el.Attribute("TestId");
    }
}

}

http://msdn.microsoft.com/en-us/library/bb387053.aspx

7.25--> A 3 24.50 B 1 89.99 A 5 4.95 A 3 66.00 B 10 .99 A 15 29.00 B 8 6.99

static void Main(string[] args)
    {

        //XmlDocument doc = new XmlDocument();
        //XmlElement newBook=doc.CreateElement("BookParticipant");
        //newBook.SetAttribute("Author");

        //Using Functional Construction to Create an XML Schema
        XElement xBookParticipant = new XElement("BookParticipant",
                                        new XElement("FirstName", "Joe"),
                                        new XElement("LastName", "Rattz"));
        Console.WriteLine(xBookParticipant.ToString());


        //Creates the Same XML Tree as Listing 6-1 but with Far Less Code
        XElement xBookParticipants = new XElement("BookParticipants",
                                        new XElement("BookParticipant",
                                        new XAttribute("type", "Author"),
                                        new XElement("FirstName", "Joe"),
                                        new XElement("LastName", "Rattz")),
                                        new XElement("BookParticipant",
                                        new XAttribute("type", "Editor"),
                                        new XElement("FirstName", "Ewan"),
                                        new XElement("LastName", "Buckingham")));
        Console.WriteLine(xBookParticipants.ToString());


        //-- Disadvatages of XML document
        //System.Xml.XmlElement xmlBookParticipant = new System.Xml.XmlElement("BookParticipant");
        XElement xeBookParticipant = new XElement("BookParticipant");


        XDocument xDocument = new XDocument(new XElement("BookParticipants",
                                            new XElement("BookParticipant",
                                            new XAttribute("type", "Author"),
                                            new XElement("FirstName", "Joe"),
                                            new XElement("LastName", "Rattz"))));
        Console.WriteLine(xDocument.ToString());


        //--Calling the ToString Method on an Element Produces the XML Tree
        XElement name = new XElement("Name", "Joe");
        Console.WriteLine(name.ToString());

        //--Console.WriteLine Implicitly Calling the ToString Method on an Element to Produce an XML Tree


        XElement name1 = new XElement("Person",
                                      new XElement("FirstName", "Joe"),
                                      new XElement("LastName", "Rattz"));
        Console.WriteLine(name1);

        //-- Casting an Element to Its Value’s Data Type Outputs the Value
        Console.WriteLine(name);
        Console.WriteLine((string)name);

        //--Different Node Value Types Retrieved via Casting to the Node Value’s Type
        XElement count = new XElement("Count", 12);
        Console.WriteLine(count);
        Console.WriteLine((int)count);

        XElement smoker = new XElement("Smoker", false);
        Console.WriteLine(smoker);
        Console.WriteLine((bool)smoker);

        XElement pi = new XElement("Pi", 3.1415926535);
        Console.WriteLine(pi);
        Console.WriteLine((double)pi);


        DeferredQryProblem();


        GenerateXMlFromLinqQry();



    }

    private static void DeferredQryProblem()
    {
        XDocument xDocument = new XDocument(
                    new XElement("BookParticipants",
                    new XElement("BookParticipant",
                    new XAttribute("type", "Author"),
                    new XElement("FirstName", "Joe"),
                    new XElement("LastName", "Rattz")),
                    new XElement("BookParticipant",
                    new XAttribute("type", "Editor"),
                    new XElement("FirstName", "Ewan"),
                    new XElement("LastName", "Buckingham"))));
        IEnumerable<XElement> elements =
        xDocument.Element("BookParticipants").Elements("BookParticipant");
        foreach (XElement element in elements)
        {
            Console.WriteLine("Source element: {0} : value = {1}",
            element.Name, element.Value);
        }
        foreach (XElement element in elements)
        {
            Console.WriteLine("Removing {0} = {1} ...", element.Name, element.Value);
            element.Remove();
        }
        Console.WriteLine(xDocument);


        foreach (XElement element in elements)
        {
            Console.WriteLine("Source element: {0} : value = {1}",
            element.Name, element.Value);
        }
        foreach (XElement element in elements.ToArray())
        {
            Console.WriteLine("Removing {0} = {1} ...", element.Name, element.Value);
            element.Remove();
        }
        Console.WriteLine(xDocument);
    }

    //-- Creating an Attribute and Adding It to Its Element
    private static void CreatingAttribute()
    {
        XElement xBookParticipant = new XElement("BookParticipant", new XAttribute("type", "Author"));
        Console.WriteLine(xBookParticipant);
    }

    //--Creating a Comment with Functional Construction
    private static void CreatingComment()
    {
        XElement xBookParticipant = new XElement("BookParticipant",
                                                  new XComment("This person is retired."));
        Console.WriteLine(xBookParticipant);
    }

    //--Creating a Declaration with Functional Construction
    private static void CreateXmlDeclaration()
    {
        XDocument xDocument = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"),
new XElement("BookParticipant"));
        Console.WriteLine(xDocument);
    }

    private static void GenerateXMlFromLinqQry()
    {
        BookParticipant[] bookParticipants = new[] {new BookParticipant {FirstName = "Joe", LastName = "Rattz",
                                                    ParticipantType = ParticipantTypes.Author},
                                                    new BookParticipant {FirstName = "Ewan", LastName = "Buckingham",
                                                    ParticipantType = ParticipantTypes.Editor}
                                                    };
        XElement xBookParticipants =
        new XElement("BookParticipants",
                     bookParticipants.Select(p =>
                new XElement("BookParticipant",
                new XAttribute("type", p.ParticipantType),
                new XElement("FirstName", p.FirstName),
                new XElement("LastName", p.LastName))));


        Console.WriteLine(xBookParticipants);
    }

    //-- Obtaining Elements Without Reaching
    private static void WithoutReaching()
    {
        XDocument xDocument = new XDocument(new XElement("BookParticipants",
                                            new XElement("BookParticipant",
                                            new XAttribute("type", "Author"),
                                            new XElement("FirstName", "Joe"),
                                            new XElement("LastName", "Rattz")),
                                            new XElement("BookParticipant",
                                            new XAttribute("type", "Editor"),
                                            new XElement("FirstName", "Ewan"),
                                            new XElement("LastName", "Buckingham"))));
        IEnumerable<XElement> elements = xDocument.Descendants("BookParticipant");
        foreach (XElement element in elements)
        {
            Console.WriteLine("Element: {0} : value = {1}",
            element.Name, element.Value);
        }


        IEnumerable<XElement> elements1 = xDocument.Descendants("BookParticipant")
                                                   .Where(e => ((string)e.Element("FirstName")) == "Ewan");
        foreach (XElement element1 in elements1)
        {
            Console.WriteLine("Element: {0} : value = {1}",
            element1.Name, element1.Value);
        }

    }
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;
        }
    }
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM