找回密码
 立即注册
首页 业界区 业界 LINQ之路20:LINQ to XML之Documents、Declarations和Na ...

LINQ之路20:LINQ to XML之Documents、Declarations和Namespaces

姘轻拎 2025-5-29 16:01:24
本篇我们会讨论与XML文档相关的另外几个重要概念:Documents、Declarations和Namespaces。一个XDocument封装了根元素并且允许我们添加XDeclaration, processing instructions, 文档类型和其他根级类型对象;一个标准的XML文件总是从一个declaration(声明)开始,它的作用是确保文件会被文件读取器正确的读取和理解;就像.NET类型可以有namespaces(命名空间)一样,XML元素和属性也可以有namespaces,用于对XML文档进行更有效的管理。
XDocument

我们前面已经说过,一个XDocument封装了根元素并且允许我们添加XDeclaration, processing instructions, 文档类型和其他根级类型对象。和W3C DOM不同的是,对于LINQ to XML中的X-DOM来讲,一个XDocument对象是可选的,X-DOM并不需要它来把所有对象联系起来。
XDocument提供了和XElement一致的函数式构造器。并且由于XDocument是从Container继承而来,所以它也支持AddXXX、RemoveXXX、和ReplaceXXX方法。但和XElement不同的是,XDocument可以接受的内容是有限制的,它可以接受如下参数:

  • 一个XElement对象(根元素)
  • 一个XDeclaration对象
  • 一个XDocumentType对象
  • 任意数量的XProcessingInstruction对象
  • 任意数量的XComment对象
要创建一个有效的XDocument,只有根元素是必须的。XDeclaration是可选的,如果它被省略,序列化时将会应用默认的设置。
一个最简单的XDocument仅有一个根元素:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var doc = new XDocument(<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>  new XElement("test", "data")<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>  );
复制代码
注意我们并没有包含XDeclaration对象,但是调用doc.Save方法生成的文件中还是会包含XML declaration信息,它会使用默认设置自动生成。
下面的示例用来生成一个简单但完全正确的XHTML文件,它很好的演示了XDocument可以接受的各种构造参数:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var styleInstruction = new XProcessingInstruction(<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>"xml-stylesheet", "href='styles.css' type='text/css'");<br> <br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var docType = new XDocumentType("html",<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>"-//W3C//DTD XHTML 1.0 Strict//EN",<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", null);<br> <br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XNamespace ns = "http://www.w3.org/1999/xhtml";<br> <br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var root = new XElement(ns + "html",<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>new XElement(ns + "head",<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>new XElement(ns + "title", "An XHTML page")),<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>new XElement(ns + "body",<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>new XElement(ns + "p", "This is the content"))<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>   );<br> <br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var doc = new XDocument(<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>  new XDeclaration("1.0", "utf-8", "no"),<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>  new XComment("Reference a stylesheet"),<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>  styleInstruction,<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>  docType,<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>  root);<br><br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>doc.Save("D:\\test.html");
复制代码
test.html文件的最终结果如下:
  1. <?xml version="1.0" encoding="utf-8" standalone="no"?><br><br><br><?xml-stylesheet href='styles.css' type='text/css'?><br><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><br><html xmlns="http://www.w3.org/1999/xhtml"><br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>   <head><br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>  <title>An XHTML page</title><br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>   </head><br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>   <body><br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>  <p>This is the content</p><br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>   </body><br></html>
复制代码
XDocument的Root属性可以用来快速的存取其唯一的XElement元素。而XObject的Document属性则可以快速访问所在的XDocument对象,X-DOM tree里面的所有对象都继承了该属性:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>Console.WriteLine(doc.Root.Name.LocalName);    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?> // html<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XElement bodyNode = doc.Root.Element(ns + "body");<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>Console.WriteLine(bodyNode.Document == doc);    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>// True
复制代码
再次强调一下,document对象的子节点并没有Parent对象:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>Console.WriteLine(doc.Root.Parent == null); // True<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>foreach (XNode node in doc.Nodes())<br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>Console.Write(node.Parent == null); // TrueTrueTrueTrue
复制代码
 
XML Declarations

一个标准的XML文件总是从一个declaration(声明)开始,如下所示:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>
复制代码
XML declaration的作用是确保文件会被文件读取器正确的读取和理解。XElement和 XDocument会遵循以下规则来处理XML declarations:

  • 提供一个文件名来调用Save方法时,总是写入declaration。
  • 提供XmlWriter来调用Save方法时,写入declaration,除非XmlWriter作了专门的指定。
  • ToString方法从不产生XML declaration。
在构造XmlWriter对象时,我们可以通过设置OmitXmlDeclaration和ConformanceLevel属性来指示XmlWriter不要产生declaration。
XDeclaration对象的存在与否并不影响是否写入XML declaration。换句话说:即使没有XDeclaration对象,Save方法也会写入默认的declaration;相反,即使存在XDeclaration对象,ToString()方法也不会产生declaration。它的目的是告知XML serialization下面的信息:

  • 使用什么字符编码(text encoding)
  • 如何设置XML declaration的encoding和standalone属性
XDeclaration的构造函数接受3个参数:version, encoding, 和standalone属性。下面的例子中,test.xml拥有UTF-16编码:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var doc = new XDocument(
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>  new XDeclaration("1.0", "utf-16", "yes"),
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>  new XElement("test", "data")
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>  );
  5.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>doc.Save("test.xml");
复制代码
实际上,XML writer会忽略第一个参数version值,而总是写入"1.0"。
 
Names和Namespaces

就像.NET类型可以有namespaces(命名空间)一样,XML元素和属性也可以有namespaces。虽然我们在一般的小项目中可能不会用到namespaces,但是在产品级的软件中,我们就必须使用它来对各种XML文档进行管理了。
XML namespaces有两个作用,首先,和C#的namespaces一样,它可以防止命名冲突。在我们把一个XML文件中的数据合并到另外一个XML文件时可能会出现。其次 ,它赋予一个Name(名称)以特别的含义。比如,名称”nil”可以表示任何东西。但是在http://www.w3.org/2001/xmlschema-instance命名空间中,“nil”表示了C#中的null语义。
因为XML命名空间非常容易引起混淆,我们将先行介绍该主题的普通含义,然后再讨论LINQ to XML对他们的使用方式。
XML中的Namespaces

假设我们希望在CNBlogs.LINQ命名空间中定义一个customer元素。那么有两种方法可以选择。第一种是使用xmlns属性,如下所示:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>
复制代码
Xmlns是一个特殊的保留属性。上例中的xmlns有两个作用:

  • 它为当前元素指定了一个命名空间。
  • 它为所有的后代节点指定了默认的命名空间。
这意味着下面的示例中,address和postcode会隐式位于CNBlogs.LINQ命名空间之中:
  1. <customer xmlns="CNBlogs.LINQ"><br>  <br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><postcode>02138</postcode><br>  </address><br></customer>
复制代码
如果我们希望address和postcode不使用命名空间,我们需要明确指定,如下所示:
  1. <customer xmlns="CNBlogs.LINQ"><br>  <br>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><postcode>02138</postcode><br>  </address><br></customer>
复制代码
前缀(Prefix)

指定命名空间的另一种方式是使用前缀。前缀是我们为命名空间指定的一个别名,目的是为了节省输入时间。
使用前缀分两步:定义前缀和使用前缀。我们可以按如下方式同时完成这两步操作:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
复制代码
在上面的代码中会发生两件特别的事情。后面的xmlns:nut="..."定义了一个名为nut的前缀,这样该元素和所有的后代节点都可以使用该前缀了。前面的nut:customer把新创建的前缀赋给了customer元素。
和xmlns不同的是,带前缀的元素并没有为后代节点指定默认的命名空间,即前缀只作用于当前元素。下面的XML中,firstname的命名空间为空:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>  Joe
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
复制代码
如要为firstname也指定CNBlogs.LINQ命名空间,我们得进行如下改写:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>  Joe
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
复制代码
当然,我们也可以为了后代节点定义一个或多个前缀,而不必在当前节点中使用它。下面的XML定义了两个前缀:i和z,但当前的customer元素命名空间保持为空:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>  ...
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
复制代码
如果customer是根节点,那么整个document都将拥有i和z命名空间。
当我们需要从多个命名空间中获取元素时,使用前缀就会非常方便,我们可以为每个命名空间定义一个前缀。
在X-DOM中指定Namespaces

到目前为止,我们只为XElement和XAttribute使用了简单的名字(一个简单的字符串)。它表示该XML name位于空的命名空间中,就像.NET全局命名空间中的类型一样。
有数种方式可以在X-DOM中指定命名空间。第一种是在名称之前的大括号中指定,如下所示:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var e = new XElement ("{http://www.cnblogs.com/xmlspace}customer", "LifePoem");
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>Console.WriteLine (e.ToString());
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>//产生的XML如下:
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>LifePoem
复制代码
第二张(更有效率)的方式是使用XNamespace和XName类型。下面是他们的定义:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>public sealed class XNamespace
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>{
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>public string NamespaceName { get; }
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>}
  5.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>public sealed class XName // 一个本地名称和一个可选的namespace
  6.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>{
  7.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>public string LocalName { get; }
  8.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>public XNamespace Namespace { get; } // 可选
  9.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>}
复制代码
这两个类型都定义了来自string的隐式转换,所以下面的代码是正确的:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XNamespace ns = "http://www.cnblogs.com/xmlspace";
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XName localName = "customer";
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XName fullName = "{http://www.cnblogs.com/xmlspace}customer";
复制代码
XName还重载了+运算符,这允许我们不使用大括号来组合namespace和name:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XNamespace ns = "http://www.cnblogs.com/xmlspace";
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XName fullName = ns + "customer";
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>Console.WriteLine(fullName); // {http://www.cnblogs.com/xmlspace}customer
复制代码
实际上,X-DOM中所有接受元素或属性名称的的构造函数和方法,其参数类型为XName而不是string。在我们前面的例子中可以使用string的原因是隐式转换。
不管是元素还是属性,指定命名空间的方式都是一样的:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XNamespace ns = "http://domain.com/xmlspace";
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var data = new XElement(ns + "data",
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>new XAttribute(ns + "id", 123)
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>);
复制代码
X-DOM和默认命名空间

在X-DOM的创建过程中它会忽略默认命名空间的概念,直到真正输出XML时才会使用默认命名空间。这意味着,我们在创建子元素时,我们必须显示指定必须的命名空间,它不会从父节点继承:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XNamespace ns = "http://www.cnblogs.com/xmlspace";
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var data = new XElement(ns + "data",
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>   new XElement(ns + "customer", "Bloggs"),
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>   new XElement(ns + "purchase", "Bicycle")
  5.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>   );
  6.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>Console.WriteLine(data.ToString());
复制代码
但是,当X-DOM读取或输出XML时,它会应用默认的命名空间,所以上面的代码输出如下:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>  Bloggs
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>  Bicycle
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
复制代码
下面的代码:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>Console.WriteLine (data.Element (ns + "customer").ToString());
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>// 输出单个元素时会加上默认的命名空间:
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>Bloggs
复制代码
如果我们在创建子XElement时没有指定命名空间,那么他们的命名空间为空,如下所示:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XNamespace ns = "http://www.cnblogs.com/xmlspace";
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var data = new XElement(ns + "data",
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>   new XElement("customer", "Bloggs"),
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>   new XElement("purchase", "Bicycle")
  5.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>   );
  6.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>Console.WriteLine(data.ToString());
复制代码
我们会得到如下结果:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>  Bloggs
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>  Bicycle
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>
复制代码
另外一个可能的陷阱是我们在导航X-DOM时没有加上适当的命名空间:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XNamespace ns = "http://www.cnblogs.com/xmlspace";
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var data = new XElement(ns + "data",
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>   new XElement(ns + "customer", "Bloggs"),
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>   new XElement(ns + "purchase", "Bicycle")
  5.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>   );
  6.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XElement x = data.Element(ns + "customer");    <nut:customer xmlns:nut="CNBlogs.LINQ"/> // 正确
  7.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XElement y = data.Element("customer");    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>  // 错误,返回null
复制代码
如果我们在创建X-DOM tree时没有指定命名空间,我们可以通过如下代码为所有元素指定一个命名空间:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>foreach (XElement e in data.DescendantsAndSelf())
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>if (e.Name.Namespace == "")
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>e.Name = ns + e.Name.LocalName;
复制代码
前缀/Prefixes

X-DOM只是把前缀作为序列化功能来使用,这意味着我们可以选择完全忽略前缀问题。唯一的例外是当我们在输出一个XML文件时为了取得更好的效率。比如,考虑下面的代码:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XNamespace ns1 = "http://www.cnblogs.com/space1";
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>XNamespace ns2 = "http://www.cnblogs.com/space2";
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>var mix = new XElement(ns1 + "data",
  4.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>new XElement(ns2 + "element", "value"),
  5.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>new XElement(ns2 + "element", "value"),
  6.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>new XElement(ns2 + "element", "value")
  7.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>);
复制代码
默认情况下,XElement会被序列化为如下格式:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>   value
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>   value
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>   value
复制代码
正如你所看到的,这里有一些没有必要的重复。解决方案不是改变创建X-DOM的方式,而是给序列化器一个暗示,用前缀来简化相关的命名空间。这可以通过添加定义前缀的属性来完成,并且通常由根元素来完成:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>mix.SetAttributeValue(XNamespace.Xmlns + "ns1", ns1);
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>    <nut:customer xmlns:nut="CNBlogs.LINQ"/><customer xmlns="CNBlogs.LINQ"/><?xml version="1.0" encoding="utf-8" standalone="no"?>    <nut:customer xmlns:nut="CNBlogs.LINQ"/>mix.SetAttributeValue(XNamespace.Xmlns + "ns2", ns2);
复制代码
这会把前缀 “ns1”赋给XNamespace变量ns1,“ns2”赋给ns2。这样X-DOM在序列化时会自动使用这些属性来简化最终的XML。下面是在mix上调用ToString方法的最终结果:
  1.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>   value
  2.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>   value
  3.     <nut:customer xmlns:nut="CNBlogs.LINQ"/>   value
复制代码
使用前缀并不改变我们创建、查询或更新X-DOM的方式,所以我们就好像前缀不存在一样继续在程序中使用全名。只有在从XML文件/流中读取或写入时才会使用前缀。
下一篇也是LINQ to XML的最后一篇,我们将会和大家讨论使用LINQ to XML来生成X-DOM的方式。
 
系列博客导航:
LINQ之路系列博客导航
LINQ之路 1:LINQ介绍
LINQ之路 2:C# 3.0的语言功能(上)
LINQ之路 3:C# 3.0的语言功能(下)
LINQ之路 4:LINQ方法语法
LINQ之路 5:LINQ查询表达式
LINQ之路 6:延迟执行(Deferred Execution)
LINQ之路 7:子查询、创建策略和数据转换
LINQ之路 8:解释查询(Interpreted Queries)
LINQ之路 9:LINQ to SQL 和 Entity Framework(上)
LINQ之路10:LINQ to SQL 和 Entity Framework(下)
LINQ之路11:LINQ Operators之过滤(Filtering)
LINQ之路12:LINQ Operators之数据转换(Projecting)
LINQ之路13:LINQ Operators之连接(Joining)
LINQ之路14:LINQ Operators之排序和分组(Ordering and Grouping)
LINQ之路15:LINQ Operators之元素运算符、集合方法、量词方法
LINQ之路16:LINQ Operators之集合运算符、Zip操作符、转换方法、生成器方法
LINQ之路17:LINQ to XML之X-DOM介绍
LINQ之路18:LINQ to XML之导航和查询
LINQ之路19:LINQ to XML之X-DOM更新、和Value属性交互
LINQ之路20:LINQ to XML之Documents、Declarations和Namespaces
LINQ之路21:LINQ to XML之生成X-DOM(Projecting)
LINQ之路系列博客后记
 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册