如何在C#中处理XML

在C#2.0中处理XML文档,XSD等的最好方法是什么?

哪些类使用等什么是parsing和制作XML文件等的最佳做法

编辑:.net 3.5的build议也欢迎。

在C#2.0中读写的主要方法是通过XmlDocument类来完成的。 您可以通过它接受的XmlReader将大部分设置直接加载到XmlDocument中。

直接加载XML

XmlDocument document = new XmlDocument(); document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>"); 

从文件加载XML

 XmlDocument document = new XmlDocument(); document.Load(@"C:\Path\To\xmldoc.xml"); // Or using an XmlReader/XmlTextReader XmlReader reader = XmlReader.Create(@"C:\Path\To\xmldoc.xml"); document.Load(reader); 

我发现读取XML文档的最简单/最快的方法是使用XPath。

使用XPath读取XML文档(使用允许我们编辑的XmlDocument)

 XmlDocument document = new XmlDocument(); document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>"); // Select a single node XmlNode node = document.SelectSingleNode("/People/Person[@Name = 'Nick']"); // Select a list of nodes XmlNodeList nodes = document.SelectNodes("/People/Person"); 

如果您需要使用XSD文档来validationXML文档,您可以使用它。

根据XSD模式validationXML文档

 XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidateType = ValidationType.Schema; settings.Schemas.Add("", pathToXsd); // targetNamespace, pathToXsd XmlReader reader = XmlReader.Create(pathToXml, settings); XmlDocument document = new XmlDocument(); try { document.Load(reader); } catch (XmlSchemaValidationException ex) { Trace.WriteLine(ex.Message); } 

在每个节点上针对XSDvalidationXML(更新1)

 XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidateType = ValidationType.Schema; settings.Schemas.Add("", pathToXsd); // targetNamespace, pathToXsd settings.ValidationEventHandler += new ValidationEventHandler(settings_ValidationEventHandler); XmlReader reader = XmlReader.Create(pathToXml, settings); while (reader.Read()) { } private void settings_ValidationEventHandler(object sender, ValidationEventArgs args) { // e.Message, e.Severity (warning, error), e.Error // or you can access the reader if you have access to it // reader.LineNumber, reader.LinePosition.. etc } 

编写XML文档(手动)

 XmlWriter writer = XmlWriter.Create(pathToOutput); writer.WriteStartDocument(); writer.WriteStartElement("People"); writer.WriteStartElement("Person"); writer.WriteAttributeString("Name", "Nick"); writer.WriteEndElement(); writer.WriteStartElement("Person"); writer.WriteStartAttribute("Name"); writer.WriteValue("Nick"); writer.WriteEndAttribute(); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndDocument(); writer.Flush(); 

(更新1)

在.NET 3.5中,您使用XDocument来执行类似的任务。 但是,不同之处在于,您可以执行Linq查询来select所需的确切数据。 通过添加对象初始化器,您可以创build一个查询,甚至可以在查询本身中直接返回自己定义的对象。

  XDocument doc = XDocument.Load(pathToXml); List<Person> people = (from xnode in doc.Element("People").Elements("Person") select new Person { Name = xnode.Attribute("Name").Value }).ToList(); 

(更新2)

在.NET 3.5中一个不错的方法是使用XDocument创buildXML如下。 这使代码以与所需输出类似的模式出现。

 XDocument doc = new XDocument( new XDeclaration("1.0", Encoding.UTF8.HeaderName, String.Empty), new XComment("Xml Document"), new XElement("catalog", new XElement("book", new XAttribute("id", "bk001"), new XElement("title", "Book Title") ) ) ); 

创build

 <!--Xml Document--> <catalog> <book id="bk001"> <title>Book Title</title> </book> </catalog> 

所有其他的失败,你可以看看这个MSDN文章,有很多我在这里讨论过的例子。 http://msdn.microsoft.com/en-us/library/aa468556.aspx

这取决于大小; 对于小到中等大小的XML,像XmlDocument (任何C#/ .NET版本)或XDocument (.NET 3.5 / C#3.0)这样的DOM是显而易见的赢家。 对于使用xsd,您可以使用XmlReader加载xml,并且XmlReader接受( 创build )一个XmlReaderSettings 。 XmlReaderSettings对象具有可用于执行xsd(或dtd)validation的Schemas属性。

对于编写xml,同样的事情也适用,注意与使用旧的XmlDocument相比,使用LINQ-to-XML(XDocument)来布局内容要容易一些。

但是,对于巨大的XML,DOM可能会占用过多的内存,在这种情况下,您可能需要直接使用XmlReader / XmlWriter。

最后,为了操纵xml,你可能希望使用XslCompiledTransform (一个xslt层)。

使用xml的替代方法是使用对象模型; 您可以使用xsd.exe创build表示符合xsd的模型的类,只需将xml 作为对象加载,使用OO进行操作,然后再次序列化这些对象; 你用XmlSerializer来做到这一点。

nyxtom的答案是非常好的。 我会添加几件事情:

如果您需要对XML文档的只读访问权限,则XPathDocument是比XmlDocument轻得多的对象。

使用XPathDocument的缺点是不能使用XmlNode熟悉的SelectNodesSelectSingleNode方法。 相反,您必须使用IXPathNavigable提供的工具:使用CreateNavigator创buildXPathNavigator ,并使用XPathNavigator创buildXPathNodeIterator以遍历通过XPathfind的节点列表。 这通常需要比XmlDocument方法多几行代码。

但是: XmlDocumentXmlNode类实现IXPathNavigable ,因此您在XPathDocument上使用这些方法编写的任何代码也都可以在XmlDocument上使用。 如果您习惯于针对IXPathNavigable进行编写, IXPathNavigable您的方法可以针对任一对象进行工作。 (这就是为什么在方法签名中使用XmlNodeXmlDocument由FxCop标记的原因。)

可悲的是, XDocumentXElement (以及XNodeXObject )不实现IXPathNavigable

另一件不存在于nyxtom的答案是XmlReader 。 您通常使用XmlReader来避免在开始处理之前将XMLstreamparsing为对象模型的开销。 而是使用XmlReader处理一个XML节点的inputstream。 这实质上是.NET对SAX的回答。 它可以让你编写非常快的代码来处理非常大的XML文档。

XmlReader还提供了处理XML文档片段的最简单方法,例如XML元素stream,不包含SQL Server的FOR XML RAW选项返回的包含元素。

您使用XmlReader编写的代码通常与其正在读取的XML格式紧密耦合。 使用XPath允许你的代码更加松散地耦合到XML,这就是为什么它通常是正确的答案。 但是当你需要使用XmlReader ,你真的需要它。

101个Linq样本

http://msdn.microsoft.com/en-us/library/bb387098.aspx

Linq XML样本

http://msdn.microsoft.com/en-us/vbasic/bb688087.aspx

我认为Linq使XML变得容易。

首先,了解新的XDocumentXElement类,因为它们是对以前的XmlDocument系列的改进。

  1. 他们使用LINQ
  2. 他们更快,更轻量

但是 ,您可能仍然需要使用旧的类来处理遗留代码 – 特别是以前生成的代理。 在这种情况下,您将需要熟悉这些XML处理类之间的互操作模式。

我觉得你的问题是相当广泛的,在一个答案中需要太多的细节,但这是我想到的第一个一般答案,并且是一个开始。

如果你在.NET 3.5中工作,并且不用担心实验代码,你可以查看LINQ to XSD( http://blogs.msdn.com/xmlteam/archive/2008/02/21/linq-to- xsd-alpha-0-2.aspx ),它将从XSD生成.NET类(包括来自XSD的内置规则)。

然后,它可以直接写入文件并从文件中读取,以确保其符合XSD规则。

我明确地build议为您使用的任何XML文档创build一个XSD:

  • 允许您在XML中执行规则
  • 允许其他人看到XML是如何被组织的
  • 可以用于validationXML

我发现Liquid XML Studio是生成XSD的好工具,它是免费的!

如果您在devise器中创build了一个types化的数据集,那么您将自动获得一个xsd,一个强types的对象,并且可以用一行代码加载和保存xml。

我个人认为,作为一名C#程序员,在C#中处理XML的最好方法是将这部分代码委托给一个VB .NET项目。 在.NET 3.5中,VB .NET具有XML Literals,这使得处理XML更加直观。 看到这里,例如:

在Visual Basic中的LINQ to XML概述

(一定要设置页面显示VB代码,而不是C#代码。)

我会用C#编写项目的其余部分,但是在引用的VB项目中处理XML。

用XmlDocument类写入XML

 //itemValues is collection of items in Key value pair format //fileName i name of XML file which to creatd or modified with content private void WriteInXMLFile(System.Collections.Generic.Dictionary<string, object> itemValues, string fileName) { string filePath = "C:\\\\tempXML\\" + fileName + ".xml"; try { if (System.IO.File.Exists(filePath)) { XmlDocument doc = new XmlDocument(); doc.Load(filePath); XmlNode rootNode = doc.SelectSingleNode("Documents"); XmlNode pageNode = doc.CreateElement("Document"); rootNode.AppendChild(pageNode); foreach (string key in itemValues.Keys) { XmlNode attrNode = doc.CreateElement(key); attrNode.InnerText = Convert.ToString(itemValues[key]); pageNode.AppendChild(attrNode); //doc.DocumentElement.AppendChild(attrNode); } doc.DocumentElement.AppendChild(pageNode); doc.Save(filePath); } else { XmlDocument doc = new XmlDocument(); using(System.IO.FileStream fs = System.IO.File.Create(filePath)) { //Do nothing } XmlNode rootNode = doc.CreateElement("Documents"); doc.AppendChild(rootNode); doc.Save(filePath); doc.Load(filePath); XmlNode pageNode = doc.CreateElement("Document"); rootNode.AppendChild(pageNode); foreach (string key in itemValues.Keys) { XmlNode attrNode = doc.CreateElement(key); attrNode.InnerText = Convert.ToString(itemValues[key]); pageNode.AppendChild(attrNode); //doc.DocumentElement.AppendChild(attrNode); } doc.DocumentElement.AppendChild(pageNode); doc.Save(filePath); } } catch (Exception ex) { } } OutPut look like below <Dcouments> <Document> <DocID>01<DocID> <PageName>121<PageName> <Author>Mr. ABC<Author> <Dcoument> <Document> <DocID>02<DocID> <PageName>122<PageName> <Author>Mr. PQR<Author> <Dcoument> </Dcouments> 

nyxtom,

例1中不应该有“doc”和“xdoc”匹配吗?

 XDocument **doc** = XDocument.Load(pathToXml); List<Person> people = (from xnode in **xdoc**.Element("People").Elements("Person") select new Person { Name = xnode.Attribute("Name").Value }).ToList(); 

Cookey的答案是好的…但是这里有关于如何从XSD(或XML)创build一个强types的对象以及在几行代码中进行序列化/反序列化的详细说明:

说明