Linq to XML - 更新/更改 XML 文档的节点
Posted
技术标签:
【中文标题】Linq to XML - 更新/更改 XML 文档的节点【英文标题】:Linq to XML - update/alter the nodes of an XML Document 【发布时间】:2010-09-24 19:04:28 【问题描述】:我有 2 个问题:
1。 我已经开始使用 Linq to XML,我想知道是否可以通过 Linq 更改 XML 文档。我的意思是,有没有类似的东西
XDocument xmlDoc = XDocument.Load("sample.xml");
update item in xmlDoc.Descendants("item")
where (int)item .Attribute("id") == id
...
2。 我已经知道如何通过简单地使用来创建和添加新的 XMLElement
xmlDoc.Element("items").Add(new XElement(......);
但是如何删除单个条目?
XML 示例数据:
<items>
<item id="1" name="sample1" info="sample1 info" web="" />
<item id="2" name="sample2" info="sample2 info" web="" />
</itmes>
【问题讨论】:
【参考方案1】:感谢您的回答。一切正常。
正如我的问题的补充,下面的代码显示了如何修改单个条目:
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");
【讨论】:
仅供参考:您可以跳过 StringReader 步骤,直接说XDocument d = XDocument.Parse(xml)
。【参考方案2】:
这是你的想法吗?
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,我们必须在代码中包含什么以确保它不会爆炸?谢谢。 这就是简洁方法之上的详细方法的用途:如果您构建列表然后对其进行迭代,如果列表为空,代码将起作用。 @Robert,无需通读 Stream,XDocument.Parse(xmlString) 即可。【参考方案3】:答案在这个帖子中......你只需要做很多排序才能找到它们,所以我已经为你完成了编译它们的工作:
-
是的,您可以编辑元素
删除元素很简单:element.Remove(); (之后记得保存 xDocument)
现在,如果您正在阅读此主题,您可能想知道如何编辑元素。在 xml 中存储数据有两种不同的方式,例如:
<tagName attributeName="some value">another value</tagName>
-
作为标签上的属性
作为标签的内容(读取值)
要编辑属性的值,knox 回答了他自己的问题:
d.Descendants("record").Where(x => x.Attribute("id").Value == "2").Single().SetAttributeValue("info", "new sample info");
也就是说,获取你想要改变的XElement,然后调用element.SetAttributeValue("AttributeName", "new value for the attribute")
如果你想编辑标签的值或内容,那么 Ajay 回答了它(如果你仔细研究了他的所有代码):
persondata.Element("City").Value = txtCity.Text;
或者,换句话说,一旦你拥有你所追求的 XElement,只需使用 .Value 并分配出去。
请记住,在对内存中的元素执行任何这些修改后,如果要将这些更改保存到磁盘,则必须在 XDocument 上调用 .Save()。
【讨论】:
【参考方案4】:使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Text; 使用 System.Xml.Linq; //使用 System.Xml;
命名空间 XMLtoLinqApp 课堂节目 静态无效主要(字符串 [] 参数)
//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--> 一种 3 24.50 乙 1 89.99 一种 5 4.95 一种 3 66.00 乙 10 .99 一种 15 29.00 乙 8 6.99
【讨论】:
【参考方案5】: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);
【讨论】:
【参考方案6】: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;
【讨论】:
仅仅插入一段代码并不能真正帮助人们,尤其是很多代码与实际问题无关以上是关于Linq to XML - 更新/更改 XML 文档的节点的主要内容,如果未能解决你的问题,请参考以下文章
c# LINQ-to-XML 更新(保存)排序后文件中的元素列表