参考文档
一、创建XML树的两种常见方式:
1、最最常见的方法:
XElement root = new XElement(new XElement("bookstore", new XElement("book", new XAttribute("genre", "谢龙宝"), new XAttribute("ISBN", "2-3631-4"), new XElement("title", "CS"), new XElement("author", "周保翠"), new XElement("price", "59.4")))); root.Save(filename);
2、使用LinQ查询的结果来填充XML树;
XElement xmltree = new XElement("Root", new XElement("child", 1), from el in srctree.Elements() where (int)el > 2 select el); xmltree.Save(Server.MapPath("bookstores.xml"));
二、内存中XML树的修改与函数构造:
就地修改 XML 树是更改 XML 文档形状的传统方法。 典型的应用程序将文档加载到数据存储区(如 DOM 或 LINQ to XML);使用编程接口插入节点、删除节点或更改节点的内容;然后将 XML 保存到文件或通过网络传输。LINQ to XML 允许使用另一种可在许多方案中使用的方法:函数构造。 函数构造将修改数据视为转换问题,而不是数据存储区的具体操作。 如果您采用某种数据表示形式并有效地将其从一种形式转换为另一种形式,其结果等效于您采用一个数据存储区并对其以某种方式进行操作以采用另一种形状。 函数构造方法的关键是将查询的结果传递给 XDocument 和 XElement 构造函数。
此示例假设您想修改下面的简单 XML 文档,使属性变为元素。 本节首先介绍传统的就地修改方法。 然后显示函数构造方法。XML文件:
<?xml version="1.0" encoding="utf-8"?> <Root Data1="123" Data2="456"> <Child1>Content</Child1> </Root>
您可以编写一些过程代码以便从属性创建元素,然后删除属性,如下所示:
XElement root = XElement.Load("Data.xml"); foreach (XAttribute att in root.Attributes()) { root.Add(new XElement(att.Name, (string)att)); } root.Attributes().Remove();
相比之下,函数方法包含用于形成新树的代码、从源树中选择元素和属性并在将其添加到新树中时进行相应的转换。 函数方法如下所示:
XElement root = XElement.Load("Data.xml"); XElement newTree = new XElement("Root", root.Element("Child1"), from att in root.Attributes() select new XElement(att.Name, (string)att) );
在本例中,函数示例一点也不比第一个示例简短,而且一点也不比第一个示例简单。 但如果要对一个 XML 树进行很多更改,则非函数方法将变得非常复杂,而且会显得很笨拙。 相比之下,使用函数方法时,您只需形成所需的 XML,嵌入适当的查询和表达式以提取需要的内容。 函数方法生成的代码更易于维护。
请注意,在本例中,函数方法的执行效果可能没有树操作方法好。 主要问题是函数方法创建了更多短生存期的对象。 但是,如果使用函数方法能够提高程序员的效率,则折中也是一种有效的方式。
这是一个很简单的示例,但它显示了这两种方法之间基本原理上的差异。 对于转换较大的 XML 文档,函数方法可以产生更高的效率增益。
向 XML 树中添加元素:
XElement srcTree = new XElement("Root", new XElement("Element1", 1), new XElement("Element2", 2), new XElement("Element3", 3), new XElement("Element4", 4), new XElement("Element5", 5) ); XElement xmlTree = new XElement("Root", new XElement("Child1", 1), new XElement("Child2", 2), new XElement("Child3", 3), new XElement("Child4", 4), new XElement("Child5", 5) ); xmlTree.Add(new XElement("NewChild", "new content")); xmlTree.Add( from el in srcTree.Elements() where (int)el > 3 select el ); xmlTree.Add(srcTree.Element("Child9"));
XElement的两个重要方法:SetElementValue() And SetAttributeValue();
旨在简化将名称/值对列表用作子元素或属性集时的维护。维护列表时,需要添加对、修改对或删除对。如果调用此方法将不存在的名称作为子元素传递,则此方法会为您创建一个子元素。如果您调用此方法来传递一个现有子元素的名称,则此方法会将此子元素的值更改为指定的值。如果您为 value 传递了 null引用,则此方法会移除子元素。
XElement root = new XElement("Root"); root.SetElementValue("Ele1", 1); root.SetElementValue("Ele1", null); root.SetAttributeValue("Att1", 1); root.SetAttributeValue("Att1", null);
最后生成的XML文档:
<?xml version="1.0" encoding="utf-8"?> <Root />
XNode.ReplaceWith 方法:
XElement root = new XElement("Root"); root.SetElementValue("Ele1", 1); root.SetElementValue("Ele2", 2); XElement ele3 = root.Element("Ele2"); ele3.ReplaceWith(new XElement("child2", "newcontent"));
从 XML 文档中移除单个元素或单个属性的操作非常简单。 但是,若要移除多个元素或属性的集合,则应首先将一个集合具体化为一个列表,然后从该列表中删除相应元素或属性。 最好的方法是使用 Remove 扩展方法,该方法可以实现此操作。
这么做的主要原因在于,从 XML 树检索的大多数集合都是用延迟执行生成的。 如果不首先将集合具体化为列表,或者不使用扩展方法,则可能会遇到某类 Bug:
下面的示例演示三种移除元素的方法。 第一种,移除单个元素。 第二种,检索元素的集合,使用 Enumerable.ToList<(Of <(TSource>)>) 运算符将它们具体化,然后移除集合。 最后一种,检索元素的集合,使用 Remove 扩展方法移除元素。
root.Element("Child1").Element("GrandChild1").Remove(); root.Element("Child2").Elements().ToList().Remove(); root.Element("Child3").Elements().Remove();