本文介绍 LINQ to XML 与当前主要 XML 编程 API W3C 文档对象模型(DOM)之间的一些主要差异。
构造 XML 树的新方法
在 W3C DOM 中,从下到上生成 XML 树;即,创建文档、创建元素,然后将元素添加到文档。
例如,以下示例使用典型的方法来使用 DOM XmlDocument的Microsoft实现创建 XML 树。
XmlDocument doc = new XmlDocument();
XmlElement name = doc.CreateElement("Name");
name.InnerText = "Patrick Hines";
XmlElement phone1 = doc.CreateElement("Phone");
phone1.SetAttribute("Type", "Home");
phone1.InnerText = "206-555-0144";
XmlElement phone2 = doc.CreateElement("Phone");
phone2.SetAttribute("Type", "Work");
phone2.InnerText = "425-555-0145";
XmlElement street1 = doc.CreateElement("Street1");
street1.InnerText = "123 Main St";
XmlElement city = doc.CreateElement("City");
city.InnerText = "Mercer Island";
XmlElement state = doc.CreateElement("State");
state.InnerText = "WA";
XmlElement postal = doc.CreateElement("Postal");
postal.InnerText = "68042";
XmlElement address = doc.CreateElement("Address");
address.AppendChild(street1);
address.AppendChild(city);
address.AppendChild(state);
address.AppendChild(postal);
XmlElement contact = doc.CreateElement("Contact");
contact.AppendChild(name);
contact.AppendChild(phone1);
contact.AppendChild(phone2);
contact.AppendChild(address);
XmlElement contacts = doc.CreateElement("Contacts");
contacts.AppendChild(contact);
doc.AppendChild(contacts);
Dim doc As XmlDocument = New XmlDocument()
Dim name As XmlElement = doc.CreateElement("Name")
name.InnerText = "Patrick Hines"
Dim phone1 As XmlElement = doc.CreateElement("Phone")
phone1.SetAttribute("Type", "Home")
phone1.InnerText = "206-555-0144"
Dim phone2 As XmlElement = doc.CreateElement("Phone")
phone2.SetAttribute("Type", "Work")
phone2.InnerText = "425-555-0145"
Dim street1 As XmlElement = doc.CreateElement("Street1")
street1.InnerText = "123 Main St"
Dim city As XmlElement = doc.CreateElement("City")
city.InnerText = "Mercer Island"
Dim state As XmlElement = doc.CreateElement("State")
state.InnerText = "WA"
Dim postal As XmlElement = doc.CreateElement("Postal")
postal.InnerText = "68042"
Dim address As XmlElement = doc.CreateElement("Address")
address.AppendChild(street1)
address.AppendChild(city)
address.AppendChild(state)
address.AppendChild(postal)
Dim contact As XmlElement = doc.CreateElement("Contact")
contact.AppendChild(name)
contact.AppendChild(phone1)
contact.AppendChild(phone2)
contact.AppendChild(address)
Dim contacts As XmlElement = doc.CreateElement("Contacts")
contacts.AppendChild(contact)
doc.AppendChild(contacts)
Console.WriteLine(doc.OuterXml)
此编码样式隐藏 XML 树的结构。 LINQ to XML 还支持替代方法 (功能构造)来更好地显示结构。 此方法可以通过使用XElement和XAttribute构造函数来完成。 在 Visual Basic 中,也可以使用 XML 文本来完成。 此示例演示了使用功能构造的同一 XML 树的构造:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144",
new XAttribute("Type", "Home")),
new XElement("phone", "425-555-0145",
new XAttribute("Type", "Work")),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
Dim contacts = _
<Contacts>
<Contact>
<Name>Patrick Hines</Name>
<Phone Type="Home">206-555-0144</Phone>
<Phone Type="Work">425-555-0145</Phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
</Contact>
</Contacts>
请注意,缩进用于构造 XML 树的代码会显示基础 XML 的结构。 Visual Basic 版本使用 XML 文本。
有关详细信息,请参阅 XML 树。
直接使用 XML 元素
使用 XML 进行编程时,主要焦点通常是 XML 元素和属性。 在 LINQ to XML 中,可以直接使用 XML 元素和属性。 例如,可以执行以下操作:
- 创建 XML 元素而不使用文档对象。 当必须使用 XML 树片段时,这简化了编程。
- 直接从 XML 文件加载
T:System.Xml.Linq.XElement
对象。 - 序列化
T:System.Xml.Linq.XElement
对象到文件或流。
将此与 W3C DOM 进行比较,其中 XML 文档用作 XML 树的逻辑容器。 在 DOM 中,必须在 XML 文档的上下文中创建 XML 节点(包括元素和属性)。 下面是在 DOM 中创建名称元素的代码片段:
XmlDocument doc = new XmlDocument();
XmlElement name = doc.CreateElement("Name");
name.InnerText = "Patrick Hines";
doc.AppendChild(name);
Dim doc As XmlDocument = New XmlDocument()
Dim name As XmlElement = doc.CreateElement("Name")
name.InnerText = "Patrick Hines"
doc.AppendChild(name)
如果要跨多个文档使用元素,则必须跨文档导入节点。 LINQ to XML 可避免这种复杂性层。
使用 LINQ to XML 时,仅当希望在文档根级别添加注释或处理指令时,才使用 XDocument 类。
简化名称和命名空间的处理
处理名称、命名空间和命名空间前缀通常是 XML 编程的复杂部分。 LINQ to XML 通过消除处理命名空间前缀的要求,简化了名称和命名空间。 如果要控制命名空间前缀,可以。 但是,如果你决定不显式控制命名空间前缀,则 LINQ to XML 将在序列化期间分配命名空间前缀(如果需要的话)或使用默认命名空间进行序列化(如果不是)。 如果使用默认命名空间,则生成的文档中不会有命名空间前缀。 有关详细信息,请参阅 命名空间概述。
DOM 的另一个问题是,它不允许更改节点的名称。 相反,必须创建新节点并将所有子节点复制到该节点,并丢失原始节点标识。 LINQ to XML 通过使你能够在节点上设置 XName 属性来避免此问题。
加载 XML 的静态方法支持
LINQ to XML 允许使用静态方法而不是实例方法加载 XML。 这简化了加载和分析。 有关详细信息,请参阅 如何从文件加载 XML。
删除对 DTD 构造的支持
LINQ to XML 通过删除对实体和实体引用的支持,进一步简化了 XML 编程。 实体的管理很复杂,很少使用。 删除其支持可以提高性能并简化编程接口。 在填充 LINQ to XML 树时,会展开所有 DTD 实体。
对片段的支持
LINQ to XML 不提供类的 XmlDocumentFragment
等效项。 但是,在许多情况下,XmlDocumentFragment
概念可以通过类型为IEnumerable<T>XNode或IEnumerable<T>XElement的查询结果来处理。
对 XPathNavigator 的支持
LINQ to XML 通过XPathNavigator命名空间中的扩展方法提供对System.Xml.XPath的支持。 有关详细信息,请参阅 System.Xml.XPath.Extensions。
对空白和缩进的支持
LINQ to XML 比 DOM 更简单地处理空白。
一种常见情形是先读取已经缩进的 XML,创建内存中的 XML 树,不保留任何空格文本节点,然后对 XML 执行一些操作,最后以缩进方式保存 XML。 使用格式序列化 XML 时,只会保留 XML 树中的显著空白。 这是 LINQ to XML 的默认行为。
另一个常见方案是读取和修改经过有意缩进的 XML 文档。 您可能不想以任何方式更改这种缩进。 在 LINQ to XML 中,可以通过以下方法执行此作:
- 加载或分析 XML 时保留空白。
- 序列化 XML 时禁用格式设置。
LINQ to XML 将空格存储为 XText 节点,而不是像 DOM 那样具有专用 Whitespace 节点类型。
支持添加批注功能
LINQ to XML 元素支持一组可扩展的批注。 这对于跟踪有关元素的其他信息非常有用,例如架构信息、有关该元素是绑定到 UI 还是任何其他应用程序特定信息的信息。 有关详细信息,请参阅 LINQ to XML 注释。
对架构信息的支持
LINQ to XML 通过命名空间中的 System.Xml.Schema 扩展方法支持 XSD 验证。 可以验证 XML 树是否符合 XSD。 可以使用架构验证后信息集(PSVI)填充 XML 树。 有关详细信息,请参阅如何使用 XSD 进行验证和 Extensions。