Подтвердить что ты не робот

Лучший способ чтения, изменения и записи XML

Мой план состоит в том, чтобы читать в документе XML с помощью моей программы на С#, искать конкретные записи, которые я хотел бы изменить, а затем выписывать измененный документ. Тем не менее, я стал отклеиваться, потому что трудно различать элементы, независимо от того, начинают ли они или заканчивают использование XmlTextReader, которые я использую для чтения в файле. Я мог бы сделать несколько советов, чтобы поставить меня на правильный путь.

Документ является HTML-документом, так как вы можете себе представить, это довольно сложно.

Я бы хотел найти идентификатор элемента в документе HTML, поэтому, например, найдите это и измените src;

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

Ответ 1

Если это действительно действительный XML и будет легко вписываться в память, я бы выбрал LINQ to XML (XDocument, XElement и т.д.) каждый раз. Это, безусловно, самый удобный XML-API, который я использовал. Легко формировать запросы и легко создавать новые элементы.

Вы можете использовать XPath, где это необходимо, или встроенные методы оси (Elements(), Descendants(), Attributes() и т.д.). Если бы вы могли сообщить нам, с какими конкретными битами вы с трудом справляетесь, я с удовольствием помогу вам разобраться, как выразить их в LINQ to XML.

Если, с другой стороны, это HTML, который не является допустимым XML, у вас будет намного сложнее время, потому что XML API generalyl ожидают работы с действительными документами 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");
}

Ответ 2

Являются ли документы, обрабатываемые относительно небольшими? Если это так, вы можете загрузить их в память с помощью объекта 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 это может сделать ваш синтаксический анализ немного проще.

Ответ 3

Здесь инструмент, который я написал, чтобы изменить файл проекта IAR EWARM (ewp), добавив в проект компоновщик. Из командной строки вы запускаете ее с двумя аргументами, именами входных и выходных файлов (*.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>

Ответ 4

Если у вас есть небольшие документы, которые соответствуют памяти компьютеров, вы можете использовать XmlDocument. В противном случае вы можете использовать XmlReader для итерации документа.

Используя XmlReader, вы можете узнать тип элементов, используя:

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

Ответ 5

Для задачи в руке - (прочитайте существующий документ, напишите и измените формализованным способом), я бы пошел с XPathDocument выполните XslCompiledTransform.

Если вы не можете формализовать, не имеете ранее существовавших документов или вообще нуждаетесь в более адаптивной логике, я бы пошел с LINQ и XDocument, как говорит Skeet.

В принципе, если задачей является преобразование, то XSLT, если задача манипулирует, то LINQ.

Ответ 6

Мой любимый инструмент для такого рода вещей 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');

Ответ 7

Просто запустите, прочитав документацию пространство имен Xml на MSDN. Тогда, если у вас есть более конкретные вопросы, разместите их здесь...

Ответ 8

Один довольно простой подход - создать новый XmlDocument, а затем использовать метод Load() для его заполнения. После того, как вы получили документ, вы можете использовать CreateNavigator(), чтобы получить объект XPathNavigator, который вы можете использовать для поиска и изменения элементов в документе. Наконец, вы можете использовать метод Save() на XmlDocument, чтобы записать измененный документ обратно.