Как найти текст в 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:
- Теги XML регистрозависимы — теги XML являются регистрозависимыми. Так, тег <Letter> не то же самое, что тег <letter> .
Открывающий и закрывающий теги должны определяться в одном регистре:
- XML элементы должны соблюдать корректную вложенность:
- У XML документа должен быть корневой элемент — XML документ должен содержать один элемент, который будет родительским для всех других элементов. Он называется корневым элементом.
- Значения XML атрибутов должны заключаться в кавычки:
Сущности¶
Некоторые символы в XML имеют особые значения и являются служебными. Если вы поместите, например, символ < внутри XML элемента, то будет сгенерирована ошибка, так как парсер интерпретирует его, как начало нового элемента.
В примере ниже будет сгенерирована ошибка, так как в значении "ООО<Мосавтогруз>" атрибута НаимОрг содержатся символы < и > .
Также ошибка будет сгенерирована и в слудющем примере, если название организации взять в обычные кавычки (английские двойные):
Чтобы ошибки не возникали, нужно заменить символ < на его сущность. В XML существует 5 предопределенных сущностей:
Сущность | Символ | Значение |
---|---|---|
< | < | меньше, чем |
> | > | больше, чем |
& | & | амперсанд |
' | ' | апостроф |
" | " | кавычки |
Только символы < и & строго запрещены в 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 файле кодировка объявляется в декларации:
Часто можно столкнуться с ситуацией, когда текстовый редаткор некорректно распознает кодировку и отображает кракозябры. В такой случае, необходимо выбрать кодировку вручную, для этого выполните:
Программа | Кодировка |
---|---|
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.
Инструкция
Язык только английский, но большинство элементов программы, которые мы будем использовать, я уже перевёл.
Первым делом нужно изменить настройки по умолчанию, зайдя в пункт меню Tools (Инструментарий) и установив метки как на скриншоте ниже:
Перевод пунктов меню смотрите ниже.
Простой способ поиска и замены
Step 1: Find. Replace with. (Шаг 1: Найти. Заменить на. )
- На вкладке Simple (Простой), в области Search for this text (Найти этот текст), вводится текст, который нужно найти и заменить; чуть ниже можно поставить метку Case Sensitive Search (Искать с учётом регистра), если нужен поиск с учётом регистра.
- В области 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 файл, который содержит следующую структуру:
3 января стартует курс «SQL-injection Master» © от команды The Codeby
За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.
На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.
Запись на курс до 10 января. Подробнее .
Выполним выше указанный код, в результате получаем исключение 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Города.
Читайте также: