C# XML技术总结之XDocument 和XmlDocument
引言
虽然现在Json在我们的数据交换中越来越成熟,但XML格式的数据还有很重要的地位。
C#中对XML的处理也不断优化,那么我们如何选择XML的这几款处理类 XmlReader,XDocument 和XmlDocument了?
本文就从对照的方式来总结C#中XML的用法。
简介
System.Xml 命名空间(XmlDocument)为处理 XML 提供基于标准的支持。
LINQ to XML(XDocument )可以进行以下操作:
从文件或流加载 XML。
将 XML 序列化为文件或流。
使用功能构造从头创建 XML 树。
使用 LINQ 查询来查询 XML 树。
操作内存中的 XML 树。
使用 XSD 验证 XML 树。
组合使用这些功能将 XML 树从一种形状转换为另一种形状。
XmlReader,XDocument 和XmlDocument
XDocument 和XmlDocument会把所有的XML所有的节点加载到内存中,而XmlReader则不会把所有节点一起加载到内存,而在一定的内存下处理较大的XML。
如果XML文件结构固定,处理比较简单,建议使用XmlReader可以提高程序的性能。
如果XML文件不大或者要做复杂的处理建议使用XDocument。Linq 让程序员省去了很多繁琐冗余的代码,并且兼容设备也比较多,不像XmlDocument在一些设备和系统中不支持。
XDocument VS. XmlDocument
| 比较项 | XmlDocument(经典DOM API) | XDocument (LINQ to XML API) |
| 需要熟悉DOM知识 | ||
| 支持的.NetFramework版本 | .NET version 1.0 + | .NET version 3.5 or later(Linq引入后) |
| 杂项 | Unity3D projects for Windows 8. Xbox 360 and Windows Phone OS 7.0,必须使用XDocument |
|
| Namespace | System.Xml | System.Xml.Linq |
| LINQ to XML | 不支持 | 支持 |
| 行号信息 | 不能提供行号信息 | 通过IXmlLineInfo提供了行号信息 |
| 命名空间 | 支持写 | 支持元素级写 |
| XPath | 不支持 | 支持, 参考System.Xml.XPath |
| 注释 | 不支持 | 支持可扩展的批注集,请参见 LINQ to XML 批注。 |
| 校验Schema | 支持,参考Validate(ValidationEventHandler) | 支持 ,参考Validate(XmlSchemaSet, ValidationEventHandler) |
| 加载XML | 成员方法加载(需要先new XmlDocument()) |
静态方法XElement.Load(@"books.xml") |


创建XML文档
使用XmlDocument 的示例
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);
使用XDocument 的示例
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")
)
)
);
加载XML文件
使用XmlDocument 的示例
XmlDocument booksFromFile = new XmlDocument();
booksFromFile.Load(@"books.xml");
使用XDocument 的示例
XElement booksFromFile = XElement.Load(@"books.xml");
命名空间的处理
使用XmlDocument 的示例
public void addXmlns()
{
string xml = @"<?xml version=""1.0""?>
<kml>
<Document>
<Placemark>
</Placemark>
</Document>
</kml>"; var xmldoc = new XmlDocument(); xmldoc.LoadXml(xml); xmldoc.DocumentElement.SetAttribute("xmlns", "http://www.opengis.net/kml/2.2");
xmldoc.DocumentElement.SetAttribute("xmlns:gx", "http://www.google.com/kml/ext/2.2");
xmldoc.DocumentElement.SetAttribute("xmlns:kml", "http://www.opengis.net/kml/2.2");
xmldoc.DocumentElement.SetAttribute("xmlns:atom", "http://www.w3.org/2005/Atom");
xmldoc.DocumentElement.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); string message;
message = xmldoc.InnerXml; Console.WriteLine(message); // shows the updated xml
}
使用XDocument 的示例
示例1,增加namespace
XNamespace ns = "http://somewhere.com";
XElement element = new XElement(ns + "elementName");
// etc
示例2,读取含有namespace的文件
string markup = @"
<aw:Root xmlns:aw='http://www.adventure-works.com'>
<aw:Child1>child one data</aw:Child1>
<aw:Child2>child two data</aw:Child2>
</aw:Root>";XmlReader reader = XmlReader.Create(new StringReader(markup));
XElement root = XElement.Load(reader);
XmlNameTable nameTable = reader.NameTable;
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(nameTable);
namespaceManager.AddNamespace("aw", "http://www.adventure-works.com");
XElement child1 = root.XPathSelectElement("./aw:Child1", namespaceManager);
Console.WriteLine(child1);
XDocument
XDocument VS. XElement
| XDocument | XElement |
| XDocument.Load() 加载整个XML文档 包括根节点 | XElement.Load()不会加载XML的根节点 |
XElement.Load()示例代码
File.WriteAllText("Test.xml", @"<Root>
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
</Root>");
Console.WriteLine("Querying tree loaded with XElement.Load");
Console.WriteLine("----");
XElement doc = XElement.Load("Test.xml");
IEnumerable<XElement> childList =
from el in doc.Elements()
select el;
foreach (XElement e in childList)
Console.WriteLine(e);
XDocument.Load() 示例代码:
File.WriteAllText("Test.xml", @"<Root>
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
</Root>");
Console.WriteLine("Querying tree loaded with XDocument.Load");
Console.WriteLine("----");
XDocument doc = XDocument.Load("Test.xml");
IEnumerable<XElement> childList =
from el in doc.Elements()
select el;
foreach (XElement e in childList)
Console.WriteLine(e);
XPath
XPath的强大之处在于处理元素导航还可以进行计算
- XPathSelectElement - Single Element
- XPathSelectElements - Node Set
- XPathEvaluate - Scalars and others
示例:
XML文档
<xml>
<foo>
<baz id="1">10</baz>
<bar id="2" special="1">baa baa</bar>
<baz id="3">20</baz>
<bar id="4" />
<bar id="5" />
</foo>
<foo id="123">Text 1<moo />Text 2
</foo>
</xml>
C#处理计算
var node = xele.XPathSelectElement("/xml/foo[@id='123']");
var nodes = xele.XPathSelectElements(
"//moo/ancestor::xml/descendant::baz[@id='1']/following-sibling::bar[not(@special='1')]");
var sum = xele.XPathEvaluate("sum(//foo[not(moo)]/baz)");
这里只是总结知识点,但具体的关于更多XPath的内容可以移步到XPath 教程
XML 批注(注释)
public class MyAnnotation
{
private string tag;
public string Tag { get { return tag; } set { tag = value; } }
public MyAnnotation(string tag)
{
this.tag = tag;
}
} class Program
{
static void Main(string[] args)
{
XElement root = new XElement("Root", "content");
root.AddAnnotation(new MyAnnotation("T1"));
root.AddAnnotation(new MyAnnotation("T2"));
root.AddAnnotation("abc");
root.AddAnnotation("def"); IEnumerable<object> annotationList;
annotationList = root.Annotations(typeof(MyAnnotation));
foreach (object ma in annotationList)
Console.WriteLine(((MyAnnotation)ma).Tag);
Console.WriteLine("----"); IEnumerable<object> stringAnnotationList;
stringAnnotationList = root.Annotations(typeof(string));
foreach (object str in stringAnnotationList)
Console.WriteLine((string)str);
}
}
总结
现在再写XML相关的程序建议直接使用XDocument,XmlDocument只是主要还是兼容以前的代码。
另外XPath功能让XDocument如虎添翼,所以大家可以多研究下XPath.
至于XSD和XSL本文不做涉及,又需要的朋友参看参考文献
参考
2.使用XmlReader读Xml,使用XmlWriter写Xml
9.W3CSchool中提供的XML相关课程
Introduction to XML and XSLT in C# .NET
C# XML技术总结之XDocument 和XmlDocument的更多相关文章
- XML技术总结之XDocument 和XmlDocument
引言 虽然现在Json在我们的数据交换中越来越成熟,但XML格式的数据还有很重要的地位. C#中对XML的处理也不断优化,那么我们如何选择XML的这几款处理类 XmlReader,XDocument ...
- C# 3.0 其他XML技术
使用XmlReader枚举结点: <?xml version="1.0" encoding="utf-8" standalone="yes&qu ...
- XDocument和XmlDocument的区别
刚开始使用Xml的时候,没有注意到XDocument和XmlDocument的区别,后来发现两者还是有一些不同的. XDocument和XmlDocument都可以用来操作XML文档,XDocumen ...
- 七、Linq To XML:XElement、XDocument
一.概述 LINQ to XMLLINQ to XML 是一种启用了 LINQ 的内存 XML 编程接口,使用它,可以在 .NET Framework.NET Framework 编程语言中处理 XM ...
- XML技术的应用
XML技术的发展历史:gml--->sml--->html--->xml(可扩展标记语言). HTML和XML技术的区别: 1.HTML技术的标签不能自己定义,必须使用规定语法编写: ...
- 打造完美的xml技术解决方案(dom4j/xstream)
转: XML 技术是随着 Java 的发展而发展起来的.在 XML 出现之前对于简单的数据格式通常是存储在 ini 配置文件等文本文件中,复杂的格式则采用自定义的文件格式,因此对于每种文件格式都要有专 ...
- xml技术DTD约束定义
XML约束 在XML技术中,可以编写一个文档来约束一个xml文档的书写规范,这称之为XML约束为什么需要XML约束? class.xml <stu><面积>?人怎么会有面积元素 ...
- 【Java】Java XML 技术专题
XML 基础教程 XML 和 Java 技术 Java XML文档模型 JAXP(Java API for XML Parsing) StAX(Streaming API for XML) XJ(XM ...
- JavaEE:Eclipse开发工具的相关使用和XML技术
Eclipse开发工具的知识点1.工程的属性(properties)1)Text file encoding 工程编码(在导入其他工程时,注意编码类型一致)2)Java build path设置cl ...
随机推荐
- Alg-4:算法可视化tiny库的实现
好吧,准备好好实践一下<算法>这本书的内容的,有点讨厌的是这本书是以Java作为示例语言的(好吧,我承认我有语言偏见,Java就是臭).其中有一个Std库,其中涉及到简化输入输出.随机数生 ...
- TeamCity : 安装 Server
本文介绍在 Ubuntu Server 14.04 中安装 TeamCity Server 10.0.1.Ubuntu Server 上已经创建了用户 tcuser.TeamCity 的安装包为 T ...
- Java中随机数的产生方式与原理
查阅随机数相关资料,特做整理 首先说一下java中产生随机数的几种方式 在j2se中我们可以使用Math.random()方法来产生一个随机数,这个产生的随机数是0-1之间的一个double,我们可以 ...
- python基础之面对对象
Python3 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前没有接触 ...
- 【工匠大道】将项目同时托管到Github和Git@OSC
原文地址 摘要: Github是最大的git代码托管平台,GIT@OSC是国内最大的git代码托管平台,支持免费私有库,支持SVN操作,用户众多.很多用户需要同时将代码托管到两个平台,这篇文章的主要 ...
- java静态方法调用&&构造函数&&静态块
静态方法,也就是使用static声明的方法,在虚拟机启动加载类的时候就进行了创建,所以使用到静态方法时,直接使用类名点静态方法即可调用.java在执行静态方法前,不会调用构造函数:构造函数是在实例化j ...
- The habits of highly successful people
1.Morning Routine (早上列行公事) Probably the most common habit ultra-successful people have is they can t ...
- 把普通对象转换成json格式的对象
1.什么叫做JSON?JSON只是一种数据格式(它不是一种新的数据类型) var obj = {name: "中国", age: 5000};//->普通格式的对象 var ...
- css水平垂直居中(绝对定位居中)
使用绝对定位有个限制就是父集必须设置一个固定的高度. 首先HTML <div id="box"> <div class="child"> ...
- 天津政府应急系统之GIS一张图(arcgis api for flex)讲解(五)地图切换以及图层显示模块
config.xml文件的配置如下: <widget right="20" top="55" config="widgets/MapSwitch ...