读取,修改和编写XML的最佳方法

时间:2010-09-17 15:04:05

标签: c# xml

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

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

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

<img border="0" src="bigpicture.png" width="248" height="36" alt="" id="lookforthis" />

8 个答案:

答案 0 :(得分:30)

如果它实际上是有效的XML,并且很容易适合内存,我每次都会选择LINQ to XMLXDocumentXElement等。它是迄今为止我用过的最好的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");
}

答案 1 :(得分:4)

您处理的文件相对较小吗?如果是这样,您可以使用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的结构,这可以使您的解析代码更简单。

答案 2 :(得分:2)

这是我编写的用于修改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的结构如下所示

    <U+FEFF><?xml version="1.0" encoding="iso-8859-1"?>
    <project>
      <fileVersion>2</fileVersion>
      <configuration>
        <name>Debug</name>
        <toolchain>
          <name>ARM</name>
        </toolchain>
        <debug>1</debug>

         ...

        <settings>
          <name>ILINK</name>
          <archiveVersion>0</archiveVersion>
          <data>

            ...

            <option>
              <name>IlinkConfigDefines</name>
              <state>MAIN_APP=0</state>
            </option>

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:1)

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

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

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

答案 5 :(得分:1)

我最喜欢的工具是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');

答案 6 :(得分:0)

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

答案 7 :(得分:-1)

首先阅读Xml namespace on the MSDN的文档。如果您有更具体的问题,请在此处发布...