Как найти текст в xml файле

Обновлено: 04.07.2024

XML ( англ. eXtensible Markup Language) — расширяемый язык разметки, предназначенный для хранения и передачи данных.

Простейший XML-документ выглядит следующим образом:

Первая строка — это XML декларация. Здесь определяется версия XML (1.0) и кодировка файла. На следующей строке описывается корневой элемент документа <book> (открывающий тег). Следующие 4 строки описывают дочерние элементы корневого элемента ( title , author , year , price ). Последняя строка определяет конец корневого элемента </book> (закрывающий тег).

Документ XML состоит из элементов (elements). Элемент начинается открывающим тегом (start-tag) в угловых скобках, затем идет содержимое (content) элемента, после него записывается закрывающий тег (end-teg) в угловых скобках.

Информация, заключенная между тегами, называется содержимым или значением элемента: <author>Erik T. Ray</author> . Т.е. элемент author принимает значение Erik T. Ray . Элементы могут вообще не принимать значения.

Элементы могут содержать атрибуты, так, например, открывающий тег <title lang="en"> имеет атрибут lang , который принимает значение en . Значения атрибутов заключаются в кавычки (двойные или ординарные).

Некоторые элементы, не содержащие значений, допустимо записывать без закрывающего тега. В таком случае символ / ставится в конце открывающего тега:

Структура XML¶

XML документ должен содержать корневой элемент. Этот элемент является «родительским» для всех других элементов.

Все элементы в XML документе формируют иерархическое дерево. Это дерево начинается с корневого элемента и разветвляется на более низкие уровни элементов.

Все элементы могут иметь подэлементы (дочерние элементы):

Правила синтаксиса (Валидность)¶

Структура XML документа должна соответствовать определенным правилам. XML документ отвечающий этим правилам называется валидным (англ. Valid — правильный) или синтаксически верным. Соответственно, если документ не отвечает правилам, он является невалидным .

Основные правила синтаксиса XML:

  1. Теги XML регистрозависимы — теги XML являются регистрозависимыми. Так, тег <Letter> не то же самое, что тег <letter> .

Открывающий и закрывающий теги должны определяться в одном регистре:

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

Сущности¶

Некоторые символы в XML имеют особые значения и являются служебными. Если вы поместите, например, символ < внутри XML элемента, то будет сгенерирована ошибка, так как парсер интерпретирует его, как начало нового элемента.

В примере ниже будет сгенерирована ошибка, так как в значении "ООО<Мосавтогруз>" атрибута НаимОрг содержатся символы < и > .

Также ошибка будет сгенерирована и в слудющем примере, если название организации взять в обычные кавычки (английские двойные):

Чтобы ошибки не возникали, нужно заменить символ < на его сущность. В XML существует 5 предопределенных сущностей:

Таблица I.1 — Сущности ¶
Сущность Символ Значение
&lt; < меньше, чем
&gt; > больше, чем
&amp; & амперсанд
&apos; ' апостроф
&quot; " кавычки

Только символы < и & строго запрещены в XML. Символ > допустим, но лучше его всегда заменять на сущность.

Таким образом, корректными будут следующие формы записей:

В последнем примере английские двойные кавычки заменены на французские кавычки («ёлочки»), которые не являются служебными символами.

Поиск информации в XML файлах (XPath)¶

XPath ( англ. XML Path Language) — язык запросов к элементам XML-документа. XPath расширяет возможности работы с XML.

XML имеет древовидную структуру. В документе всегда имеется корневой элемент (инструкция <?xml version=”1.0”?> к дереву отношения не имеет). У элемента дерева всегда существуют потомки и предки, кроме корневого элемента, у которого предков нет, а также тупиковых элементов (листьев дерева), у которых нет потомков. Каждый элемент дерева находится на определенном уровне вложенности (далее — «уровень»). У элементов на одном уровне бывают предыдущие и следующие элементы.

Это очень похоже на организацию каталогов в файловой системе, и строки XPath, фактически, — пути к «файлам» — элементам. Рассмотрим пример списка книг:

XPath запрос /bookstore/book/price вернет следующий результат:

Сокращенная форма этого запроса выглядит так: //price .

В приведенной ниже таблице представлены некоторые выражения XPath и результат их работы:

Кодировки¶

И еще один важный момент, который стоит рассмотреть — кодировки. Существует множество кодировок, о них подробнее можно прочитать в статье Набор символов.

Самыми распространенными кириллическими кодировками являются Windows-1251 и UTF-8 . Последняя является одним из стандартов, но большая часть ФНС отчетности имеет кодировку Windows-1251 .

В XML файле кодировка объявляется в декларации:

Часто можно столкнуться с ситуацией, когда текстовый редаткор некорректно распознает кодировку и отображает кракозябры. В такой случае, необходимо выбрать кодировку вручную, для этого выполните:

Таблица I.3 — Смена кодировки в разных программах ¶
Программа Кодировка
Notepad++ «Документ → Кодировка»
Geany «Документ → Установить кодировку»
Firefox «Вид → Кодировка»
Chrome «Настройка → Дополнительные инструменты → Кодировка»

В большинстве случаев при работе с русскоязычными файлами помогает переключение кодировки на Windows-1251 или UTF-8 . Если все равно не удается прочитать содержимое XML документа, стоит открыть его в Mozilla Firefox, он отлично распознает кодировки.

Если ничего не помогает, вполне возможно, что файл был поврежден.

XSD схема¶

XML Schema — язык описания структуры XML-документа, его также называют XSD. Как большинство языков описания XML, XML Schema была задумана для определения правил, которым должен подчиняться документ. Но, в отличие от других языков, XML Schema была разработана так, чтобы её можно было использовать в создании программного обеспечения для обработки документов XML.

После проверки документа на соответствие XML Schema читающая программа может создать модель данных документа, которая включает:

  • словарь (названия элементов и атрибутов);
  • модель содержания (отношения между элементами и атрибутами и их структура);
  • типы данных.

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

Программа не работает с файлами doc , docx и mp3 . На других форматах её работоспособность не проверялась.

Search And Replace работает с кодировкой UTF-8.

Инструкция

Язык только английский, но большинство элементов программы, которые мы будем использовать, я уже перевёл.

Настройки программы Search And Replace

Первым делом нужно изменить настройки по умолчанию, зайдя в пункт меню Tools (Инструментарий) и установив метки как на скриншоте ниже:

Перевод пунктов меню смотрите ниже.

Простой способ поиска и замены

Step 1: Find. Replace with. (Шаг 1: Найти. Заменить на. )

  1. На вкладке Simple (Простой), в области Search for this text (Найти этот текст), вводится текст, который нужно найти и заменить; чуть ниже можно поставить метку Case Sensitive Search (Искать с учётом регистра), если нужен поиск с учётом регистра.
  2. В области Replace found text with this text (Заменить найденный текст на следующий) пишется текст, на который нужно заменить найденный.

Step 2: Where to replace (files etc) (Шаг 2: Где заменить (файлы и так далее))

Drag'n'Drop (Перетащить) Перетаскиваем на соответствующую область файлы, в которых нужно найти и заменить текст: Specify Directory (Указать папку) Выбираем папку, в которой находятся файлы для поиска и замены, с помощью кнопки Browse (Обзор); также, в случае необходимости, активируем опции Include subdirectories (Включая вложенные папки) и All files (Все файлы) или указываем расширения файлов через точку с запятой без пробела (.html;.php;.txt;. ) в соответствующем поле: Рекомендую всегда указывать конкретные расширения файлов (.html;.php;.txt;. ), так как иначе программа может (если обнаружит совпадения) автоматически заменить код «нетекстовых» файлов (например, изображений), что приведёт к их порче. Text (like notepad) (Текст (как блокнот)) В указанную область пишем текст, в котором нужно найти и заменить другой текст:

Шаг 3: Нажать кнопку Search and Replace (Найти и Заменить)

Пример для простого способа

Результат будет следующий: четыре плюс четыр е надцать равно икс

Поиск и замена по способу «От. До. »

Заменяя текст по этому способу, следует учесть то, что в области ЗАМЕНИТЬ НА нужно писать также текст областей ОТ и ДО (см. пример).

Пример для способа «От. До. »

Опция Case Sensitive Search (Искать с учётом регистра), в этом случае, должна быть активирована.

Добавление текста

Удаление текста

Перевод

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

Из этой статьи Вы узнаете, как найти xml элемент по его атрибуту с помощью простого LINQ запроса. И так для начала создадим Windows Forms приложение и поместим на форму: два элемента управления textBox (txtAtrName и txtAtrValue), кнопку и один listBox. Затем добавим в наш проект xml файл, который содержит следующую структуру:

Windows forms приложение

3 января стартует курс «SQL-injection Master» © от команды The Codeby

За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

Запись на курс до 10 января. Подробнее .

найденные xml элементы

Выполним выше указанный код, в результате получаем исключение NullReferenceException.

исключение

Чтобы этого избежать нужно, добавить в Linq запрос проверку на null. То есть сначала мы должны убедиться, что XML атрибут существует, а только потом получить его значение.

Теперь всё в порядке.

1 декабря стартует зимний поток курса " Тестирование Веб-Приложений на проникновение " от команды codeby . Общая теория, подготовка рабочего окружения, пассивный фаззинг и фингерпринт, активный фаззинг, уязвимости, пост-эксплуатация, инструментальные средства, Social Engeneering и многое другое. На курс можно записаться до 10 декабря включительно. Подробнее .

2 thoughts to “Как найти xml элемент по его атрибуту в XML файле?”

Привет. А как найденное вывести в dataGridView1 (я ее уже создал)?
Два варианта:
1) вручную создать столбцы
2) автоматически создать столбцы

Имеем XML-данные, в которых содержится традиционная для нашей книги таблица с именами и телефонами, причем имена в этой телефонной табличке по­вторяются, например, строка с именем "Витя" содержит мобильный телефон, а по­том по мере знакомства с этим Витей у нас появился уже и его домашний телефон. Задача состоит в том, чтобы в данной таблице телефонов (представленной в виде XML, см. листинг 11.8) найти все строчки с именем "Витя". Эта маленькая несерь­езная, на первый взгляд, задача подразумевает, например, такую уже "серьезную" задачу. Имеем громадную базу данных, которую мы получили на каком-то этапе обработки в виде XML, и нам требуется "отфильтровать" записи в этой базе на предмет содержания в некотором поле определенной строки.

Прежде чем решать данную задачу, давайте посмотрим отображение обсуж­даемых XML-данных в табличном редакторе MS Excel (рис. 19.11).


Рисунок 19.11 - Отображение XML-данных в MS Excel

Как видно, в редакторе MS Excel наши XML-Данные представлены весьма на­глядно. И очень понятно, что мы хотим получить, а именно, все номера телефонов напротив имени "Витя".

Для решения этой задачи запустим Visual Studio 2010 и выберем проект шабло­на Windows Forms Application, укажем имя Name — Linq5. Далее, попав в конст­руктор формы, из панели элементов Toolbox перетащим текстовое поле TextBox для вывода в него найденных строк из таблицы XML. В свойствах текстового поля разрешим ввод множества строк (а не одной), для этого свойство Multiline пере­ведем в состояние true. Затем на вкладке программного кода введем текст, пред­ставленный в листинге 19.8.

Листинг 19.8. Извлечение значения элемента из XML-данных

// Имеем XML-данные, в которых содержатся таблица с именами и телефонами, причем

// имена в этой телефонной табличке повторяются. Задача состоит в том, чтобы в

// данной таблице телефонов (представленной в виде XML) найти все строчки c

// именем "Витя" с помощью LINQ-запроса.

// Другие директивы using удалены, поскольку они не используются в данной программе

public partial class Form1 : Form

this.Text = "LINQ-запрос к XML-данным"; textBox1.Multiline = true;

<Номера_телефонов>274 28 44</Номера_телефонов>

<Номера_телефонов>099 72 161 52</Номера_телефонов>

<Номера_телефонов>254 67 97</Номера_телефонов>

var КорневойЭлемент = System.Xml.Linq.XElement.Parse(СтрокаXML);

// Запись строки, содержащей XML в файл:

// var КорневойЭлемент = System.Xml.Linq.

from x in КорневойЭлемент.Elements("Строка")

// Вывод коллекции записей в текстовое поле textBox1:

foreach (var x in Записи)

textBox1.Text = textBox1.Text + x + "\r\n";

// Таких записей в этой коллекции - ровно одна

Как видно, в начале программы мы инициализируем (т. е. присваиваем началь­ные значения) XML-строку. Далее извлекаем корневой элемент из XML-документа, он, по сути, отличается от XML-документа отсутствием XML-объявления (в этом можно убедиться в отладчике программы). В комментарии указано, как можно полу­чить корневой элемент в том случае, если он представлен в виде XML-файла во внешней памяти. Затем организуем типовой, стандартный LINQ-запрос. Результат запроса попадает в коллекцию записей, которую выводим в текстовое поле, исполь­зуя оператор цикла foreach. Фрагмент работы программы показан на рис. 19.12.


Рисунок 19.12 - LINQ-запрос к XML-документу

Убедиться в работоспособности программы можно, открыв решение Linq5.sln из папки Linq5.

5.8 LINQ-запрос к набору данных DataSet

Весьма полезной оказывается организация LINQ-запросов к наборам данных DataSet, используемым, к примеру, при работе с базами данных. Объект класса DataSet представляет расположенный в памяти кэш (cache) данных (кэш — это промежуточная память с быстрым доступом, содержащая информацию, которая может быть запрошена с наибольшей вероятностью). Реляционные базы данных работают чаще всего с совокупностью таблиц. Каждая из этих таблиц задается как объект класса DataTable, один такой объект представляет ровно одну таблицу дан­ных. Набор данных DataSet содержит в себе несколько объектов (таблиц) DataTable. Запросы LINQ к таблицам данных, кэшированным в объекте DataSet, упрощают и ускоряют процесс отбора.

Данная задача состоит в том, чтобы создать программу, которая обеспечивает ввод простейшей таблицы, содержащей два поля — название города и численность его населения. Программа способна фильтровать данные в таблице; будем произво­дить отбор городов, численность населения которых превышает миллион жителей.

Для решения этой задачи запустим Visual Studio 2010 и выберем проект шаблона Windows Forms Application, укажем имя Name — LinqГорода. Далее, попав в кон­структор формы, из панели элементов Toolbox перетащим элемент управления для отображения и редактирования табличных данных DataGridView, две командные кнопки Button и текстовое поле TextBox. Одна кнопка предназначена для команды сохранения данных, другая — для поиска данных в таблице, а текстовое поле — для вывода в него найденных строк из таблицы. В свойствах текстового поля разрешим ввод множества строк, для этого свойство Multiline переведем в состояние true. Затем на вкладке программного кода введем текст, представленный в листинге 19.9.

Листинг 19.9. Извлечение полей из набора данных DataSet

// В данной программе экранная форма содержит элемент управления для отображения

// и редактирования табличных данных DataGridView, две командные кнопки и текстовое

// поле. При старте программы, если есть соответствующий файл XML, то программа

// отображает в DataGridView таблицу городов - название города и численность

// населения. При щелчке на кнопке "Сохранить" все изменения в таблице записываются

// в XML-файл. При щелчке на второй кнопке "Найти" выполняется LINQ-запрос к набору

// данных DataSet на поиск городов-миллионеров в искомой таблице. Результат запроса

// выводится в текстовое поле.

// Другие директивы using удалены, поскольку они не используются в данной программе

public partial class Form1 : Form

DataTable Таблица = new DataTable(); // Создание объекта таблица данных

DataSet НаборДанных = new DataSet(); // Создание объекта набор данных

base.Text = "LINQ-запрос к набору данных DataSet";

button1.Text = "Сохранить"; button2.Text = "Найти";

if (System.IO.File.Exists("Города.xml") == false)

// Если XML-файла НЕТ:

// Заполнение "шапки" таблицы

// Добавить объект Таблица в DataSet

else // Если XML-файл ЕCТЬ:

// Содержимое DataSet в виде строки XML для отладки:

// string СтрокаXML = НаборДанных.GetXml();

private void button1_Click(object sender, EventArgs e)

// Щелчок мышью на кнопке "Сохранить" - сохранить файл Города.xml:

private void button2_Click(object sender, EventArgs e)

// Щелчок мышью на кнопке "Поиск" - запрос городов-миллионеров:

textBox1.Clear(); // - очистка текстового поля

var ГородаМлн = from Город in Таблица.AsEnumerable()

textBox1.Text = textBox1.Text + "Города-миллионеры:\r\n";

// Вывод результата запроса в текстовое поле textBox1:

foreach (var Город in ГородаМлн)

textBox1.Text = textBox1.Text + Город.A + " - " + Город.B + "\r\n";

В начале программы создаем объекты классов DataSet и DataTable так, чтобы они были видимыми из всех процедур класса Form1. Далее сразу после инициали­зации компонентов экранной формы (т. е. после выполнения процедуры InitializeComponent) проверяем, существует ли файл Города.xml, куда мы запи­сываем искомую таблицу. Если файл не существует, т. е. пользователь первый раз запустил нашу программу, то мы создаем таблицу, состоящую из двух полей (ко­лонок): "Город" и "Население", добавляем (Add) эту таблицу в набор данных, а также указываем таблицу в качестве источника данных (DataSource) для сетки данных dataGridView1. Если же файл Города.xml уже создан, то мы читаем его в набор данных DataSet и из него заполняем таблицу данных, а также этот набор данных указываем в качестве источника для сетки данных.

При обработке события "щелчок мышью на кнопке Запись” программируем сохранение редактируемой таблицы в файле Города.хml. В процедуре обработки события "щелчок на кнопке" Найти организуем LINQ-запрос к заполненной поль­зователем таблице DataTable, являющейся представителем DataSet. Условием за­проса является отбор таких полей таблицы, где население превышает миллион жи­телей. Заметим, что если не задавать условие where, то в результате запроса получим все содержимое источника данных, т. е. все строки таблицы городов. Ре­зультат запроса выводим в текстовое поле, используя цикл foreach.

Фрагмент работы программы показан на рис. 19.13.

Убедиться в работоспособности программы можно, открыв решение LinqГорода.sln из папки LinqГорода.

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