1. Темы лекции: Работа с XML.
Практическое задание: Работа с XML.
Тренер: Игорь Шкулипа, к.т.н.
С++ Библиотеки STL и Qt. Занятие 6
2. http://www.slideshare.net/IgorShkulipa 2
Файловый ввод-вывод
Qt предоставляет свою собственную поддержку операций для работы с
файлами, состоящую из следующих классов:
• QDir — для работы с директориями;
• QFile — для работы с файлами;
• QFileInfо — для получения файловой информации;
• QIODevice — абстрактный класс для ввода/вывода;
• QBuffer — для буферизации файлов в памяти компьютера.
3. http://www.slideshare.net/IgorShkulipa 3
QIODevice
QIODevice — это абстрактный класс, обобщающий устройство
ввода/вывода, который содержит виртуальные методы для открытия и
закрытия устройства ввода/вывода, а также для чтения и записи
блоков данных или отдельных символов.
Реализация конкретного устройства происходит в унаследованных
классах.
В Qt есть четыре класса, наследующие класс QIODevice:
• QFile — класс для проведения операций с файлами;
• QBuffer — позволяет записывать и считывать данные в массив
QByteArray, как будто бы это устройство или файл;
• QAbstractSocket — базовый класс для сетевой коммуникации
посредством сокетов.
• QProcess — этот класс предоставляет возможность запуска
процессов с дополнительными аргументами и позволяет
обмениваться информацией с этими процессами посредством
методов, определенных в QIODevice.
4. http://www.slideshare.net/IgorShkulipa 4
Открытие QIODevice
Для работы с устройством его необходимо открыть в одном из режимов,
определенных В заголовочном файле класса QIODevice.
Для того чтобы в любой момент времени исполнения программы узнать, в
каком из режимов было открыто устройство, нужно вызвать метод
openMode().
• QIODevice::NotOpen — устройство не открыто (это значение не имеет
смысла передавать в метод open());
• QIODevice::ReadOnly — открытие устройства только для чтения данных;
• QIODevice::writeOnly — открытие устройства только для записи данных;
• QIODevice::ReadWrite — открытие устройства для чтения и записи данных
(то же, что и IO_ReadOnly | IO_WriteOnly);
• QIODevice::Append — открытие устройства для добавления данных;
• QIODevice::Unbuffered — открытие для непосредственного доступа к
данным, в обход промежуточных буферов чтения и записи;
• QIODevice::Text — применяются преобразования символов переноса
строки в зависимости от платформы. Для ОС Windows, например — rn, а
для MacOS X и UNIX — /r;
• QIODevice::Truncate — все данные устройства, по возможности, должны
быть удалены при открытии.
5. http://www.slideshare.net/IgorShkulipa 5
Чтение-запись
Считывать и записывать данные можно с помощью методов read() и
write() соответственно. Для чтения всех данных сразу определен
метод readAll(), который возвращает их в объекте типа QByteArray.
Строку или символ можно прочитать методами readLine() и getChar()
соответственно.
В классе QIODevice определен метод для смены текущего положения
seek(). Получить текущее положение можно вызовом метода pos(). Но
не забывайте, что эти методы применимы только для прямого доступа
к данным. При последовательном доступе, каким является сетевое
соединение, они теряют смысл. Более того, в этом случае теряет смысл
и метод size(), возвращающий размер данных устройства. Все эти
операции применимы только для QFile, QBuffer и QTemporaryFile.
Для создания собственного класса устройства ввода/вывода, для которого
Qt не предоставляет поддержки, необходимо унаследовать класс
QIODevice и реализовать в нем методы readData() и writeData(). В
большинстве случаев может потребоваться перезаписать методы
open(), close() и atEnd().
6. http://www.slideshare.net/IgorShkulipa 6
XML
XML (eXtensible Markup Language, или расширяемый язык разметки) — это
язык описания документов, во многом похожий на язык разметки
гипертекста HTML, но гораздо более универсальный, чем HTML.
XML — текстовый формат, предназначенный для хранения
структурированных данных (взамен существующих файлов баз
данных), для обмена информацией между программами, а также для
создания на его основе более специализированных языков разметки
(например, XHTML), иногда называемых словарями.
Пример:
<?xml version="1.0"?>
<list_of_items>
<item id="1">
<first/>Первый</item>
<item id="2">Второй
<sub_item>подпункт 1</sub_item>
</item>
<last/>Последний</item>
</list_of_items>
7. http://www.slideshare.net/IgorShkulipa 7
Формат XML-файла
Первая строка XML документа называется объявлением XML (declaration) это
необязательная строка, указывающая версию стандарта XML. Здесь может быть
указана кодировка символов и внешние зависимости.:
<?xml version="1.0" encoding=“windows-1251"?>
Далее идут элементы документа, разделенные открывающими и закрывающими
тэгами. Каждый элемент имеет имя, которым начинается открывающий тэг
элемента и заканчивается закрывающий.
Содержимым элемента (content), называется всё, что расположено между
открывающим и закрывающим тегами. Все значения атрибутов должны быть в
одинарных или двойных кавычках. Каждый XML документ обязательно содержит
один корневой элемент (report) и сколько угодно вложенных элементов (place,
measurement). Любой вложенный элемент также может иметь свои вложенные
элементы.
Комментарии вводятся конструкцией:
<!-- Текст комментария -->
Текстовые данные в XML называются сущностью (entity). Текст может содержать
спецсимволы (некоторые символы запрещены) ссылки на сущность (entity
references). Кодировка спецсимволов в XML аналогична HTML:
& &
< <
> >
' '
" "
пробел.
8. http://www.slideshare.net/IgorShkulipa 8
В 1980-е годы был разработан - SGML (Standard Generalized Markup
Language)
◦ разработан для МО США; задача - снизить расходы на передачу
документации
◦ четкая иерархическая структурированность информации;
◦ расширяемость стандарта
◦ отделение информации от представления (использование DTD -
Document Type Definition)
◦ слишком сложен для реализации в Web (Sounds Good, Maybe Later)
Предыстория XML: SGML
9. http://www.slideshare.net/IgorShkulipa 9
• Документ называется действительным, если он имеет связанное с
ним определение типа документа (схему) и соответствует ему
• В XML 1.0 единственным типом схем является DTD – Document Type
Definition
• DTD основано на упрощенном формате SGML и было создано для
нужд EDI (Electronic Data Interchange)
• Синтаксис DTD существенно отличается от XML
Определение типа документа (DTD)
<!ELEMENT Joke (Setup, Punchline) >
<!ATTLIST Joke author CDATA #REQUIRED
firstTold CDATA #IMPLIED >
<!ELEMENT Setup (#PCDATA) >
<!ELEMENT Punchline (#PCDATA) >
<?xml version="1.0"?>
<!DOCTYPE Joke SYSTEM "Joke.dtd">
<Joke author="Groucho Marx">
<Setup>Outside of a dog, a book is man's
best friend</Setup>
<Punchline>Inside of a dog, it's too dark
to read.</Punchline>
</Joke>
10. http://www.slideshare.net/IgorShkulipa 10
Проблемы DTD
● DTD - строго иерархический формат, плохо подходящий для
меняющихся документов
● У документа может быть только один тип, что не очень удобно для
коммерческих приложений
● Синтаксис DTD не похож на XML и плохо воспринимается человеком
● В DTD допустимо использование только текстового типа данных (нет
числового типа или даты)
11. http://www.slideshare.net/IgorShkulipa 11
XML-схемы
● Схемы должны следовать синтаксису XML
● Стандарт схемы должен поддерживать распространенные типы данных
(число, дата…)
● Схема XML должна быть открытой для подключения внешних источников
● Метод разрешения неоднозначности имен при соединении двух файлов -
пространства имен.
12. http://www.slideshare.net/IgorShkulipa 12
XML Schema
XML Schema – промышленный стандарт описания XML-документов
XML Schema делает следующее:
• Описывает названия элементов и атрибутов (словарь).
• Описывает взаимосвязь между элементами и атрибутами, а также
их структуру (модель содержания).
• Описывает типы данных.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="книга" type="Книга" />
<xs:complexType name="Книга">
<xs:sequence>
<xs:element name="название" type="xs:string" />
<xs:element name="цена" type="xs:decimal" />
</xs:sequence>
</xs:complexType>
</xs:schema>
13. http://www.slideshare.net/IgorShkulipa 13
Document Object Model
• Объектная модель документа открывает доступ к XML-документу как к
древовидной структуре в памяти
• Позволяет работать с XML-документом как с обычным объектом в
любом современном языке программирования
• Перед началом работы DOM требует загрузки всего документа в
память (поэтому разрабатываются и альтернативные стандарты)
• Стандарт оставляет разработчикам большую свободу в интерпретации
• Microsoft предлагает MS XML DOM 3.0, интегрированную в продукты
Microsoft
XPath
XPath (XML Path Language) — язык запросов к элементам XML-документа.
Разработан для организации доступа к частям документа XML в файлах
трансформации XSLT и является стандартом консорциума W3C. XPath
призван реализовать навигацию по DOM в XML
14. http://www.slideshare.net/IgorShkulipa 14
XSLT
XSLT (eXtensible Stylesheet Language Transformations) — язык
преобразования XML-документов. Спецификация XSLT входит в состав
XSL и является рекомендацией W3C.
При применении таблицы стилей XSLT, состоящей из набора шаблонов, к
XML-документу (исходное дерево) образуется конечное дерево, которое
может быть сериализовано в виде XML-документа, XHTML-документа,
HTML-документа или простого текстового файла.
XSLT имеет множество различных применений, в основном в области web-
программирования и генерации отчётов. Одной из задач, решаемых
языком XSLT, является отделение данных от их представления, как часть
общей парадигмы MVC.
XQuery
XQuery — язык запросов, разработанный для обработки данных в
формате XML. XQuery использует XML как свою модель данных.
15. http://www.slideshare.net/IgorShkulipa 15
Достоинства XML
• XML — язык разметки, позволяющий отобразить двоичные данные в текст,
читаемый человеком и анализируемый компьютером;
• XML поддерживает Юникод;
• в формате XML могут быть описаны такие структуры данных как записи, списки и
деревья;
• XML — это самодокументируемый формат, который описывает структуру и имена
полей так же как и значения полей;
• XML имеет строго определённый синтаксис и требования к анализу, что
позволяет ему оставаться простым, эффективным и непротиворечивым.
Одновременно с этим, разные разработчики не ограничены в выборе
экспрессивных методов (например, можно моделировать данные, помещая
значения в параметры тегов или в тело тегов, можно использовать различные
языки и нотации для именования тегов и т. д.);
• XML — формат, основанный на международных стандартах;
• Иерархическая структура XML подходит для описания практически любых типов
документов, кроме аудио и видео мультимедийных потоков, растровых
изображений, сетевых структур данных и двоичных данных;
• XML представляет собой простой текст, свободный от лицензирования и каких-
либо ограничений;
• XML не зависит от платформы;
16. http://www.slideshare.net/IgorShkulipa 16
Достоинства XML
• XML является подмножеством SGML (который используется с 1986 года). Уже
накоплен большой опыт работы с языком и созданы специализированные
приложения;
• XML не накладывает требований на расположение символов в строке;
• В отличие от бинарных форматов, XML содержит метаданные об именах, типах и
классах описываемых объектов, по которым приложение может обработать
документ неизвестной структуры (например, для динамического построения
интерфейсов);
• XML имеет реализации парсеров для всех современных языков
программирования;
• XML поддерживается на низком аппаратном, микропрограммном и программном
уровнях в современных аппаратных решениях.
17. http://www.slideshare.net/IgorShkulipa 17
Недостатки XML
• Синтаксис XML избыточен.
• Размер XML-документа существенно больше бинарного представления тех же
данных. В грубых оценках величину этого фактора принимают за 1 порядок (в
10 раз).
• Размер XML-документа существенно больше, чем документа в альтернативных
текстовых форматах передачи данных (например JSON, YAML) и особенно в
форматах данных, оптимизированных для конкретного случая использования.
• Избыточность XML может повлиять на эффективность приложения. Возрастает
стоимость хранения, обработки и передачи данных.
• XML содержит метаданные (об именах полей, классов, вложенности структур), и
одновременно XML позиционируется как язык взаимодействия открытых систем.
При передаче между системами большого количества объектов одного типа
(одной структуры), передавать метаданные повторно нет смысла, хотя они
содержатся в каждом экземпляре XML описания.
• Для большого количества задач не нужна вся мощь синтаксиса XML и можно
использовать значительно более простые и производительные решения.
• Неоднозначность моделирования.
• Нет общепринятой методологии для моделирования данных в XML, в то время
как для реляционной модели и объектно-ориентированной такие средства
разработаны и базируются на реляционной алгебре, системном подходе и
системном анализе.
18. http://www.slideshare.net/IgorShkulipa 18
Недостатки XML
• В природе есть множество объектов и явлений, для описания которых разные структуры
данных (сетевая, реляционная, иерархическая) являются естественными, и отображение
объекта в неестественную для него модель является болезненным для его сути. В случае с
реляционной и иерархической моделями определены процедуры декомпозиции,
обеспечивающие относительную однозначность, чего нельзя сказать о сетевой модели.
• В результате большой гибкости языка и отсутствия строгих ограничений, одна и та же
структура может быть представлена множеством способов (различными разработчиками),
например, значение может быть записано как атрибут тега или как тело тега и т. д. Например:
<a b="1" c="1"/> или <a b="1" c="1"></a> или <a><b>1</b><c>1</c></a> или <a><c
value="1"/></a> или <a><fields b="1" c="1"/></a> и т. д.
• Поддержка многих языков в именовании тегов дает возможность назвать, например вес
русским словом, в таком случае компьютер никак не сможет установить соответствия этого
поля с полем weight в англоязычной версии программы и с полями в версиях модели объекта
на множестве других языков.
• XML не содержит встроенной в язык поддержки типов данных. В нём нет строгой типизации, то
есть понятий «целых чисел», «строк», «дат», «булевых значений» и т. д.
• Иерархическая модель данных, предлагаемая XML, ограничена по сравнению с реляционной
моделью и объектно-ориентированными графами и сетевой моделью данных.
• Выражение неиерархических данных (например графов) требует дополнительных усилий.
• Кристофер Дейт, специалист в области реляционных баз данных, автор классического
учебника «An Introduction to Database Systems», отмечал, что «…XML является попыткой
заново изобрести иерархические базы данных…» (в 1980-е года иерархические базы данных
были вытеснены реляционными базами данных).
• Пространства имён XML сложно использовать и их сложно реализовывать в XML-парсерах.
• Существуют другие, обладающие сходными с XML возможностями, текстовые форматы данных,
которые обладают более высоким удобством чтения человеком (YAML, JSON, SweetXML, XF).
19. http://www.slideshare.net/IgorShkulipa 19
XML в Qt
Qt обеспечивает два программных интерфейса для чтения XML – SAX и
DOM, эти интерфейсы входят в состав QtXml.
• SAX – Simple API for XML. Позволяет обрабатывать события
синтаксического анализа непосредственно в приложении в
соответствующих виртуальных методах.
• DOM – Document Object Model. Преобразует документ XML в
древовидную структуру, которая затем может обрабатываться в
приложении.
20. http://www.slideshare.net/IgorShkulipa 20
Чтение XML при помощи SAX
Qt обеспечивает построенный на основе интерфейса SAX парсер
документов XML, не предусматривающий проверку их достоверности
под названием QXmlSimpleReader.
Этот парсер распознает хорошо сформированные документы XML и
поддерживает пространства имен XML. Когда парсер обрабатывает
документ, он вызывает виртуальные функции в зарегистрированных
классах—обработчиках, уведомляющих о возникновении
соответствующих событий в ходе синтаксического анализа документа.
При чтении документа, парсер вызовет следующие обработчики событий
синтаксического анализа:
• startDocument()
• startElement()
• characters()
• endElement()
• endDocument()
Все приведенные выше функции объявлены в абстрактном классе
QXmlContentHandler и должны быть реализованы в конкретном
обработчике.
21. http://www.slideshare.net/IgorShkulipa 21
Пример. XML
<?xml version="1.0"?>
<books>
<book id="11111">
<name>Song of Ice and Fire</name>
<author>George R.R. Martin</author>
<pages>100500</pages>
<year>2011</year>
<language>English</language>
</book>
<book id="22222">
<name>War and Peace</name>
<author>Lev Tolstoy</author>
<pages>200500</pages>
<year>1869</year>
<language>Russian</language>
</book>
</books>
29. http://www.slideshare.net/IgorShkulipa 29
Чтение XML при помощи DOM
DOM обеспечивает интерфейс для доступа и изменения содержимого и
структуры XML файла. Он создаёт иерархическое отображение
документа (в виде дерева). Эта -- в отличие о интерфейса SAX2 --
объектная модель документа составляется в памяти после анализа
документа, что делает её лёгкой для изменений.
Все узлы DOM в дереве документа являются подклассами QDomNode.
Сам документ представляется объектом QDomDocument.
32. http://www.slideshare.net/IgorShkulipa 32
Запись документов XML
Существует два основных подхода создания XML-файлов в приложениях
Qt:
• Построить дерево DOM и затем вызвать метод save().
• Вручную создать XML-файл
Выбор того или иного метода зависит от используемого парсера - SAX или
DOM.
36. http://www.slideshare.net/IgorShkulipa 36
Паттерн Memento (Хранитель)
Назначение паттерна Memento:
• Не нарушая инкапсуляции, паттерн Memento получает и сохраняет
за пределами объекта его внутреннее состояние так, чтобы позже
можно было восстановить объект в таком же состоянии.
• Является средством для инкапсуляции "контрольных точек"
программы.
• Паттерн Memento придает операциям "Отмена" (undo) или "Откат"
(rollback) статус "полноценного объекта".
Паттерн проектирования Memento определяет трех различных
участников:
• Originator (хозяин) - объект, умеющий создавать хранителя, а
также знающий, как восстановить свое внутреннее состояние из
хранителя.
• Caretaker (смотритель) - объект, который знает, почему и когда
хозяин должен сохранять и восстанавливать себя.
• Memento (хранитель) - "ящик на замке", который пишется и
читается хозяином и за которым присматривает смотритель.
47. http://www.slideshare.net/IgorShkulipa 47
Лабораторная работа №6. XML
Добавить к тетрису возможность сохранения текущего состояния игры в
формате XML.
Данные, которые необходимо сохранять для каждого пользователя:
• проведенные игры с момента логина пользователя
• дата/время, продолжительность игр
• счет в каждой игре
• если последняя игра не закончена, то ее текущее состояние