Очистить xml файл c

Обновлено: 06.07.2024

Я редко обращаюсь за помощью, но это сводит меня с ума: я читаю xml файл, который обертывает произвольное количество элементов, каждый из которых имеет b64-кодированный файл (и некоторые сопутствующие ему метаданные). Первоначально я просто прочитал весь файл в XmlDocument , но в то время как это был намного более чистый код, я понял, что нет ограничений на размер файла, а XmlDocument ест много памяти и может закончиться, если файл достаточно большой. Поэтому я переписал код, вместо этого использую XmlTextReader , который отлично работает, если проблема в том, что программе был отправлен xml файл с большим количеством вложений с достаточным размером. но все еще большая проблема, и что, когда я перехожу к вы:

Если мой читатель xml находится в элементе File, этот элемент содержит значение, которое огромно (скажем, 500 МБ), и я вызываю reader.ReadElementContentAsString() , теперь у меня есть строка, которая занимает 500 МБ (или, возможно, OutOfMemoryException). То, что я хотел бы сделать в любом случае, это просто записать в журнал, "это вложение файлов было слишком большим, мы будем игнорировать его и двигаться дальше", а затем переходить к следующему файлу. Но не кажется, что строка, которую я только что пробовал читать, когда-либо собиралась в мусор, так что на самом деле происходит то, что строка занимает всю ОЗУ, и каждый другой файл, который он пытается прочитать после этого, также генерирует исключение OutOfMemoryException, хотя большинство файлов будет довольно небольшим.

Вспомните: на данный момент я читаю значение элемента в локальной строке, поэтому я ожидал, что он будет немедленно принят к сбору мусора (и что это будет, таким образом, сбор мусора, самое позднее, когда программа попытается прочитайте следующий элемент и узнайте, что у него нет памяти). Но я все испробовал, на всякий случай: установка строки в нуль, вызов явного GC.Collect() . no dice, диспетчер задач указывает, что GC собрал только около 40k, из

500MB он просто попросил сохранить string in, и я все еще получаю исключения из памяти, пытаясь прочитать что-нибудь еще.

Кажется, нет никакого способа узнать длину значения, содержащегося в элементе xml, используя XmlTextReader не читая этот элемент, поэтому я думаю, что я застрял, читая строку. Я что-то упустил или действительно невозможно прочитать гигантское значение из xml файла без полного разрушения вашей способности программы делать что-нибудь еще после этого? Я сойду с ума.

Дайте мне знать, если вам нужна дополнительная информация, и спасибо!

Короче говоря; У меня есть много пустых строк, сгенерированных в XML файле, и я ищу способ удалить их как способ наклонения файла. Как я могу это сделать?

Подробное объяснение; В настоящее время у меня есть этот XML файл:

И я использую этот код Java для удаления всех тегов и вместо этого добавляю новые:

После выполнения этого метода несколько раз я получаю XML файл с правильными результатами, но со многими пустыми строками после тега "paths" и перед первым тегом "path", например:

------------------------------------------- Изменить: Добавить код getXMLFile (. ), saveXMLFile (. ).

ОТВЕТЫ

Ответ 1

Это приведет к удалению всех сгенерированных пустых пространств в файле XML.

Особая благодарность MadProgrammer за комментирование с помощью полезной ссылки, упомянутой выше.

Ответ 2

Во-первых, объяснение того, почему это происходит - что может быть немного не так, поскольку вы не включили код, который используется для загрузки файла XML в объект DOM.

Когда вы читаете XML-документ из файла, пробелы между тегами фактически составляют действительные узлы DOM, в соответствии со спецификацией DOM. Поэтому синтаксический анализатор XML обрабатывает каждую такую последовательность пробелов как узел DOM (типа TEXT );

Чтобы избавиться от этого, есть три подхода, которые я могу придумать:

setValidating(true) XML со схемой, а затем используйте setValidating(true) вместе с setIgnoringElementContentWhitespace(true) в DocumentBuilderFactory .

(Примечание: setIgnoringElementContentWhitespace будет работать только в том случае, если анализатор находится в режиме проверки, поэтому вы должны использовать setValidating(true) )

Для этого используйте код Java: используйте XPath, чтобы найти все узлы TEXT только для пробелов, выполнить итерацию по ним и удалить каждый из своих родительских узлов (используя getParentNode().removeChild() ). Нечто подобное может подойти ( doc будет вашим объектом документа DOM):

Ответ 3

Вы можете посмотреть на что-то вроде this, если вам нужно просто "очистить" ваш xml быстро. Тогда у вас может быть такой метод:

Кроме того, чтобы сравнить различия в проверке anche, если вам это нужно: XMLUnit

Ответ 4

У меня возникла такая же проблема, и я долго не знала, но теперь, после этого вопроса Брэда и его собственного ответа по его собственному вопросу, я выяснил, в чем проблема.

Я должен добавить свой собственный ответ, потому что Брэд один не совсем совершенен, как сказал Исаак:

Я бы не стал большим поклонником слепого удаления дочерних узлов, не зная, что они представляют.

Итак, лучшее "решение" (цитируется, потому что это скорее всего обходное решение):

Это полностью удаляет ненужные пустые строки. Это определенно лучше, чем удаление всех дочерних узлов. Брэд, это тоже сработает для вас.

Но это эффект, а не причина, и мы получили, как удалить этот эффект, а не причину.

Причиной является: когда мы вызываем removeChild() , он удаляет это дочерние элементы, но оставляет отступ удаляемого дочернего элемента, а также прерывание строки. И этот indent_and_like_break рассматривается как текстовое содержимое.

Ответ 5

Я использую код ниже:

Ответ 6

Несколько замечаний: 1) Когда вы манипулируете XML (удаляя элементы/добавляя новый), я настоятельно рекомендую вам использовать XSLT (а не DOM) 2) Когда вы транслируете XML-документ с помощью XSLT (как и в методе сохранения), установите для OutputKeys.INDENT значение "нет", 3) Для простой последующей обработки вашего xml (удаление пробелов, комментариев и т.д.) Вы можете использовать простой фильтр SAX2

Ответ 7

Ответ 8

Существует очень простой способ избавиться от пустых строк, если используется API обработки DOM (например, DOM4J):

  • поместите текст, который вы хотите сохранить в переменной (т.е. text )
  • установите для текста node значение "" с помощью node.setText("")
  • установите для node текст text с помощью node.setText(text)

et voila! больше нет пустых строк. Другие ответы очень хорошо определяют, как лишние пустые строки в выводе xml на самом деле являются дополнительными узлами текста типа.

Этот метод может использоваться с любой системой разбора DOM, если имя функции настройки текста изменено в соответствии с тем, что указано в вашем API, и, следовательно, способ представлять его несколько более абстрактно.

Уроки программирования, алгоритмы, статьи, исходники, примеры программ и полезные советы


За основу XML-данных мы возьмём слегка видоизмененный код из статьи о считывании XML-файла в программу. А именно будем создавать подобные записи:

Внешний вид

Выглядеть наша программа будет вот так:

У на нашей форме находятся следующие элементы: TextBox, NumericUpDown, ComboBox, а также кнопки и элемент DataGridView, разбитый на три столбца и занимающий большую часть формы.

В этом окне можно настроить имя, ширину и прочие свойства столбцов. Также стоит ознакомиться с некоторыми изменениями в свойствах данного элемента, которые мы внесли (в исходном файле, который можно скачать внизу статьи). Для удобства использования и избежания некоторых ошибок мы запретили в DataGridView добавлять строки, выбирать более одной строки, а также редактировать данные.

Добавление данных

Далее переходим к коду. Перво-наперво нам надо подключить библиотеку IO:

Данная библиотека отвечает за загрузку, запись и чтение файлов. Она нам понадобится, потом что мы в итоге будем сохранять наш файл на диск.

Для этого в коде кнопки пишем следующее:

private void button1_Click ( object sender , EventArgs e ) //Добавление данных в форму dataGridView1 . Rows [ n ] . Cells [ 0 ] . Value = textBox1 . Text ; // столбец Name dataGridView1 . Rows [ n ] . Cells [ 1 ] . Value = numericUpDown1 . Value ; // Age dataGridView1 . Rows [ n ] . Cells [ 2 ] . Value = comboBox1 . Text ; // Programmer

Сохранение XML-файла

Итак, мы можем добавить сколько угодно записей. Теперь надо их сохранить как один XML-файл.

private void button4_Click ( object sender , EventArgs e ) //сохранение данных из формы в XML DataSet ds = new DataSet ( ) ; // создаем пока что пустой кэш данных DataTable dt = new DataTable ( ) ; // создаем пока что пустую таблицу данных ds . Tables . Add ( dt ) ; //в ds создается таблица, с названием и колонками, созданными выше foreach ( DataGridViewRow r in dataGridView1 . Rows ) // пока в dataGridView1 есть строки DataRow row = ds . Tables [ "Employee" ] . NewRow ( ) ; // создаем новую строку в таблице, занесенной в ds row [ "Name" ] = r . Cells [ 0 ] . Value ; //в столбец этой строки заносим данные из первого столбца dataGridView1 row [ "Age" ] = r . Cells [ 1 ] . Value ; // то же самое со вторыми столбцами row [ "Programmer" ] = r . Cells [ 2 ] . Value ; //то же самое с третьими столбцами ds . Tables [ "Employee" ] . Rows . Add ( row ) ; //добавление всей этой строки в таблицу ds. MessageBox . Show ( "XML файл успешно сохранен." , "Выполнено." ) ; MessageBox . Show ( "Невозможно сохранить XML файл." , "Ошибка." ) ;

По сути мы просто создаем кэш данных под названием ds, затем в этот кэш заносим таблицу со столбцами Name, Age и Programmer.

Затем при помощи оператора цикла foreach, который работает с группами объектов (например, со столбцами и строками таблицы) создаем строку с тремя столбцами, в каждый из которых записываем данные из соответствующих столбцов dataGridView.

В XML-файл данные из ds переводятся автоматически при помощи метода WriteXml.

DataRow row = ds . Tables [ "Employee" ] . NewRow ( ) ; // создаем новую строку в таблице, занесенной в ds

Количество таких тегов будет равно количеству строк в DataGridView и, соответственно, количеству строк в ds.

row [ "Name" ] = r . Cells [ 0 ] . Value ; //в столбец этой строки заносим данные из первого столбца dataGridView1 row [ "Age" ] = r . Cells [ 1 ] . Value ; // то же самое со вторыми столбцами row [ "Programmer" ] = r . Cells [ 2 ] . Value ; //то же самое с третьими столбцами

Сохранение данного XML-файла будет произведено по пути, записанному в скобках следующей строки:

В данном случае файл сохраняется на диск G и имеет название Data.xml.

Важно: проверьте, имеет ли Visual Studio права для сохранения данных на выбранный вами диск. Если у него не будет для этого прав, то появится ошибка и файл не будет сохранен.

Мы научились добавлять и сохранять XML-файл при помощи класса DataSet и элемента DataGridView.

Загрузка XML-файла

private void button5_Click ( object sender , EventArgs e ) //загрузка файла XML в форму if ( dataGridView1 . Rows . Count > 0 ) //если в таблице больше нуля строк MessageBox . Show ( "Очистите поле перед загрузкой нового файла." , "Ошибка." ) ; if ( File . Exists ( "G:\\Data.xml" ) ) // если существует данный файл DataSet ds = new DataSet ( ) ; // создаем новый пустой кэш данных ds . ReadXml ( "G:\\Data.xml" ) ; // записываем в него XML-данные из файла foreach ( DataRow item in ds . Tables [ "Employee" ] . Rows ) int n = dataGridView1 . Rows . Add ( ) ; // добавляем новую сроку в dataGridView1 dataGridView1 . Rows [ n ] . Cells [ 0 ] . Value = item [ "Name" ] ; // заносим в первый столбец созданной строки данные из первого столбца таблицы ds. dataGridView1 . Rows [ n ] . Cells [ 1 ] . Value = item [ "Age" ] ; // то же самое со вторым столбцом dataGridView1 . Rows [ n ] . Cells [ 2 ] . Value = item [ "Programmer" ] ; // то же самое с третьим столбцом

Таким образом происходит загрузка XML-файла.

Редактирование данных

Теперь сделаем возможность редактирования данных для XML-файла.

Итак, для начала мы переходим в события элемента DataGridView (значок молнии), ищем там MouseClick и щёлкаем на поле рядом с ним два раза:

Как разобрать XML в C++

Программирование и разработка

Как разобрать XML в C++

В этой статье мы собираемся обсудить, как анализировать XML на языке программирования C ++. Мы увидим несколько рабочих примеров, чтобы понять механизм синтаксического анализа XML в C ++.

Что такое XML?

XML — это язык разметки, который в основном используется для хранения и передачи данных в организованном порядке. XML означает расширяемый язык разметки. Он очень похож на HTML. XML полностью ориентирован на хранение и передачу данных, тогда как HTML используется для отображения данных в браузере.

Пример XML-файла / XML-синтаксиса

Вот пример XML-файла:

Разбор библиотек в C ++:

Существуют различные библиотеки для анализа XML-данных на большинстве языков программирования высокого уровня. C ++ не исключение. Вот самые популярные библиотеки C ++ для анализа XML-данных:

Как следует из названия, RapidXML в основном ориентирован на скорость и представляет собой библиотеку синтаксического анализа в стиле DOM. PugiXML поддерживает преобразование Unicode. Вы можете использовать PugiXML, если хотите преобразовать документ UTF-16 в UTF-8. TinyXML — это минимальная версия для анализа XML-данных, которая не такая быстрая по сравнению с двумя предыдущими. Если вы хотите просто выполнить свою работу и не заботитесь о скорости, вы можете выбрать TinyXML.

Примеры

Теперь у нас есть базовое понимание XML и библиотек синтаксического анализа XML в C ++. Давайте теперь рассмотрим пару примеров для синтаксического анализа XML-файла на C ++:

  • Пример-1: синтаксический анализ XML в C ++ с использованием RapidXML
  • Пример-2: синтаксический анализ XML в C ++ с использованием PugiXML
  • Пример-3: синтаксический анализ XML в C ++ с использованием TinyXML

В каждом из этих примеров мы будем использовать соответствующие библиотеки для анализа образца XML-файла.

Пример-1: синтаксический анализ XML в C ++ с использованием RapidXML

В этом примере программы мы продемонстрируем, как анализировать xml с помощью библиотеки RapidXML на C ++. Вот исходный XML-файл (sample.xml):

Наша цель здесь — проанализировать указанный выше XML-файл с помощью C ++. Вот программа на C ++ для анализа XML-данных с помощью RapidXML. Вы можете скачать библиотеку RapidXML отсюда.

синтаксический анализ XML в C ++ с использованием RapidXML

Пример-2: синтаксический анализ XML в C ++ с использованием PugiXML

В этом примере программы мы продемонстрируем, как анализировать xml с помощью библиотеки PugiXML на C ++. Вот входной XML-файл (sample.xml):

В этом примере программы мы продемонстрируем, как анализировать xml с помощью библиотеки pugixml на C ++. Вы можете скачать библиотеку PugiXML отсюда.

синтаксический анализ XML в C ++ с использованием PugiXML

Пример-3: синтаксический анализ XML в C ++ с использованием TinyXML

В этом примере программы мы продемонстрируем, как анализировать xml с помощью библиотеки TinyXML на C ++. Вот входной XML-файл (sample.xml):

В этом примере программы мы продемонстрируем, как анализировать xml с помощью библиотеки TinyXML на C ++. Вы можете скачать библиотеку TinyXML отсюда.

синтаксический анализ XML в C ++ с использованием TinyXML

Заключение

В этой статье мы кратко обсудили XML и рассмотрели три различных примера синтаксического анализа XML в C ++. TinyXML — это минималистичная библиотека для анализа XML-данных. Большинство программистов в основном используют RapidXML или PugiXML для анализа XML-данных.

Читайте также: