如何在C#中处理XML

Mal*_*har 82 .net c# xml

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

使用哪些类等.解析和制作XML文档等的最佳实践是什么?

编辑:.Net 3.5建议也欢迎.

nyx*_*tom 175

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

直接加载XML

XmlDocument document = new XmlDocument();
document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>");
Run Code Online (Sandbox Code Playgroud)

从文件加载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);
Run Code Online (Sandbox Code Playgroud)

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

使用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");
Run Code Online (Sandbox Code Playgroud)

如果需要使用XSD文档来验证XML文档,可以使用它.

根据XSD架构验证XML文档

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); }
Run Code Online (Sandbox Code Playgroud)

在每个节点上针对XSD验证XML(更新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
}
Run Code Online (Sandbox Code Playgroud)

编写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();
Run Code Online (Sandbox Code Playgroud)

(更新1)

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

    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();
Run Code Online (Sandbox Code Playgroud)

(更新2)

.NET 3.5中的一个很好的方法是使用XDocument来创建XML.这使得代码以与所需输出类似的模式显示.

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")
                    )
              )
        );
Run Code Online (Sandbox Code Playgroud)

创建

<!--Xml Document-->
<catalog>
  <book id="bk001">
    <title>Book Title</title>
  </book>
</catalog>
Run Code Online (Sandbox Code Playgroud)

所有其他方法都失败了,你可以查看这篇MSDN文章,其中有很多我在这里讨论的例子以及更多. http://msdn.microsoft.com/en-us/library/aa468556.aspx

  • 您可能想要指出您在上一个示例中使用的是XDocument,因为XDocument与XmlDocument完全不同 (3认同)
  • 更正; 没有C#3.5;你的意思是.NET 3.5和C#3.0 (2认同)

Mar*_*ell 30

这取决于大小; 对于中小型xml,诸如XmlDocument(任何C#/ .NET版本)或XDocument(.NET 3.5/C#3.0)之类的DOM 显然是赢家.对于使用xsd,您可以使用XmlReader加载xml ,XmlReader接受(创建)XmlReaderSettings.XmlReaderSettings对象具有Schemas属性,可用于执行xsd(或dtd)验证.

对于编写xml,同样适用,注意使用LINQ-to-XML(XDocument)布局内容比使用旧版XmlDocument要容易一些.

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

最后,对于操作xml,您可能希望使用XslCompiledTransform(xslt层).

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


Rob*_*ney 12

nyxtom的答案非常好.我要添加一些东西:

如果您需要对XML文档的只读访问权限,XPathDocument那么它的权重要轻得多XmlDocument.

使用的缺点XPathDocument是你不能使用熟悉的SelectNodesSelectSingleNode方法XmlNode.相反,您必须使用提供的工具IXPathNavigable:用于CreateNavigator创建XPathNavigator,并使用XPathNavigator创建XPathNodeIterators来迭代通过XPath找到的节点列表.这通常需要比XmlDocument方法多一些代码行.

但是:XmlDocumentXmlNode类实现IXPathNavigable,所以你编写的任何代码使用这些方法XPathDocument也将工作XmlDocument.如果您习惯于反对写作IXPathNavigable,那么您的方法可以对任何一个对象起作用.(这就是为什么使用XmlNodeXmlDocument在方法签名中由FxCop标记的原因.)

可悲的是,XDocumentXElement(和XNodeXObject)不执行IXPathNavigable.

在nyxtom的答案中没有出现的另一件事是XmlReader.通常XmlReader用来避免在开始处理XML流之前将XML流解析为对象模型的开销.相反,您使用an一次XmlReader处理一个XML节点的输入流.这基本上是.NET对SAX的回答.它允许您编写非常快速的代码来处理非常大的XML文档.

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

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

  • 请注意,有一个扩展方法[`XPathNavigator CreateNavigator(此XNode节点)`](http://msdn.microsoft.com/en-us/library/bb299124.aspx)从`XNode`创建`XPathNavigator` (包括派生类`XDocument`). (3认同)

小智 5

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

  1. 他们使用 LINQ
  2. 它们更快更轻

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

我认为您的问题非常广泛,并且需要在单个答案中提供太多细节才能提供详细信息,但这是我想到的第一个通用答案,并且可以作为一个开始。