Как эффективно редактировать XML-файл большого размера?

#c# #xml

Вопрос:

Итак, в основном у меня есть большой XML-файл, в котором более 300 000 строк. Это выглядит так:

 lt;TextFieldgt;  lt;IDgt;41445lt;/IDgt;  lt;Textgt;Passing overlt;/Textgt; lt;/TextFieldgt; lt;TextFieldgt;  lt;IDgt;1123lt;/IDgt;  lt;Textgt;Press ESC to get back into the menult;/Textgt; lt;/TextFieldgt;  

Я создал консольную программу для чтения файла с помощью xmlDocument и повторения каждого узла для перевода текста:

 foreach (XmlNode item in nodeList) {  if (item.SelectSingleNode("Text") != null)  {  if (!re.IsMatch(item["Text"].InnerText)) //check if text is empty or number only  item["Text"].InnerText = translate(item["Text"].InnerText, "en", "fr"); //trans from 1 to 2  } }  

В основном способ перевода занимает 0,5-1 сек, поэтому с файлами, в которых так много строк, в моем случае более 300 000, что, вероятно, займет у меня целую вечность, чтобы закончить перевод этого файла. У вас есть лучший способ сделать это быстрее? Я подумываю о том, чтобы разделить узлы на небольшие части и позволить каждому потоку выполнять работу отдельно. Но я действительно не знаю, как это сделать. Спасибо.

Комментарии:

1. Почему перевод занимает так много времени?

2. @CodeCaster Ну, я использую API Яндекс-перевода для выполнения работы по переводу, и мне требуется столько времени, чтобы вернуть переведенный текст. Вероятно, просто задержка из-за того, что они находятся далеко от своего сервера.

3. вы можете разделить свой xml-файл и перевести их с помощью задачи, я думаю, что это будет первым…

4. Как я понимаю, вы запрашиваете API перевода на каждой итерации цикла. Это означает, что должно быть сделано много ответов на запросы. Как насчет того, чтобы поместить каждое InnerText значение в список строк, а затем запросить API перевода, чтобы перевести все эти строки в один текст (привет string.Join ). Затем в ответ просто разделите переведенный текст на отдельные строки и вернитесь к узлам?

Ответ №1:

Использование XML Linq происходит очень быстро. Попробуйте следовать :

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.Xml.Linq;  namespace ConsoleApplication4 {  class Program  {  const string FILENAME = @"c:temptest.xml";  static void Main(string[] args)  {  XDocument doc = XDocument.Load(FILENAME);   Dictionarylt;string, stringgt; dict = doc.Descendants("TextField")  .GroupBy(x =gt; (string)x.Element("ID"), y =gt; (string)y.Element("Text"))  .ToDictionary(x =gt; x.Key, y =gt; y.FirstOrDefault());  }  } }