阅读,修改和编写XML的最佳方式

我的计划是使用我的C#程序读取XML文档,搜索我想要更改的特定条目,然后写出修改后的文档。 但是,我已经变得不稳定,因为很难区分元素,无论它们是使用XmlTextReader开始还是结束,我正在使用它来读取文件。 我可以提出一些建议让我走上正轨。

该文档是一个HTML文档,因此您可以想象,它非常复杂。

我想在HTML文档中搜索元素id,例如查找并更改src;

 

如果它实际上是有效的XML,并且很容易适合内存,我每次都会选择LINQ to XML ( XDocumentXElement等)。 它是迄今为止我用过的最好的XML API。 它很容易形成查询,也很容易构建新元素。

您可以在适当的地方使用XPath,或者使用内置轴方法( Elements()Descendants()Attributes()等)。 如果您能告诉我们您遇到的具体问题,我很乐意帮助您了解如何在LINQ to XML中表达它们。

另一方面,如果这是不是有效XML的HTML,那么您将面临更加困难的时间 – 因为XML API通常希望使用有效的XML文档。 您当然可以先使用HTMLTidy ,但这可能会产生不良影响。

对于您的具体示例:

 XDocument doc = XDocument.Load("file.xml"); foreach (var img in doc.Descendants("img")) { // src will be null if the attribute is missing string src = (string) img.Attribute("src"); img.SetAttributeValue("src", src + "with-changes"); } 

您处理的文件相对较小吗? 如果是这样,您可以使用XmlDocument对象将它们加载到内存中,修改它,然后将更改写回。

 XmlDocument doc = new XmlDocument(); doc.Load("path_to_input_file"); // Make changes to the document. using(XmlTextWriter xtw = new XmlTextWriter("path_to_output_file", Encoding.UTF8)) { xtw.Formatting = Formatting.Indented; // optional, if you want it to look nice doc.WriteContentTo(xtw); } 

根据输入XML的结构,这可以使您的解析代码更简单一些。

这是我编写的用于修改IAR EWARM项目(ewp)文件的工具,为项目添加了一个链接器定义。 在命令行中,使用2个参数(输入和输出文件名(* .ewp))运行它。

  using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; namespace ewp_tool { class Program { static void Main(string[] args) { XmlDocument doc = new XmlDocument(); doc.Load(args[0]); XmlNodeList list = doc.SelectNodes("/project/configuration[name='Debug']/settings[name='ILINK']/data/option[name='IlinkConfigDefines']/state"); foreach(XmlElement x in list) { x.InnerText = "MAIN_APP=1"; } using (XmlTextWriter xtw = new XmlTextWriter(args[1], Encoding.UTF8)) { //xtw.Formatting = Formatting.Indented; // leave this out, it breaks EWP! doc.WriteContentTo(xtw); } } } } 

XML的结构如下所示

    2  Debug  ARM  1 ...  ILINK 0  ...  

如果您有适合计算机内存的较小文档,则可以使用XmlDocument 。 否则,您可以使用XmlReader遍历文档。

使用XmlReader您可以使用以下方法找出元素类型:

 while (xml.Read()) { switch xml.NodeType { case XmlNodeType.Element: //Do something case XmlNodeType.Text: //Do something case XmlNodeType.EndElement: //Do something } } 

对于手头的任务 – (以正式方式读取现有文档,编写和修改),我将使用XPathDocument运行XslCompiledTransform 。

如果你不能正式化,没有预先存在的文档或者通常需要更多的自适应逻辑,我会像Skeet所说的那样使用LINQ和XDocument。

基本上如果任务是转换然后XSLT,如果任务是操纵然后LINQ。

我最喜欢的这类工具是HtmlAgilityPack 。 我用它来将复杂的HTML文档解析为LINQ可查询的集合。 它是查询和解析HTML(通常不是有效的XML)的极其有用的工具。

对于您的问题,代码如下所示:

 var htmlDoc = HtmlAgilityPack.LoadDocument(stringOfHtml); var images = htmlDoc.DocumentNode.SelectNodes("//img[id=lookforthis]"); if(images != null) { foreach (HtmlNode node in images) { node.Attributes.Append("alt", "added an alt to lookforthis images."); } } htmlDoc.Save('output.html'); 

一种相当简单的方法是创建一个新的XmlDocument ,然后使用Load()方法填充它。 获得文档后,可以使用CreateNavigator()获取可用于查找和更改文档中元素的XPathNavigator对象。 最后,您可以使用XmlDocument上的Save()方法将已更改的文档写回。

首先阅读MSDN上的Xml命名空间的文档。 如果您有更具体的问题,请在此处发布…