Объект XML

From SunFlurry wiki
Jump to: navigation, search
  XML (Объект XML)
Статус разработки: Реализован
Создание объекта: XML.Create

Объект XML используется для работы с файлами в формате XML (Extensible Markup Language). Формат является подмножеством формата веб-страниц HTML и служит как один из основных форматов для обмена произвольной текстовой информацией. За многие годы использования, XML накопил много сложностей и исключений, поэтому одинаковый по содержимому XML-файл может выглядеть абсолютно по-разному как для человека (при отсутствии или наличии форматирования и кодирования отдельных знаков), так и для машины, разбирающей текст (использование или не использование пространств имен или указаний на схемы проверки формата в атрибутах тегов). При выборе формата обмена данными, разработчик должен хорошо подумать, прежде чем остановить свой выбор на XML. Сложность стандарта формата ведет к повышенному потреблению памяти и замедлению работы с большими файлами обмена на многих платформах. Данный объект оптимизирован для высокой скорости работы, однако, создания новых файлов XML с нуля будет всегда быстрее с помощью простого наращивания строки (см. функцию см. AppendStringToBufferedString). Более того, часто проще и понятней читать XML-файлы с помощью текстового разбора. Из-за сложности формата, однако, перед текстовым разбором XML необходимо использовать функцию ReformatXML.

Важно: при добавлении значений в ветки или атрибуты с помощью функций объекта нужно помнить, что система не кодирует в значениях запрещенные знаки автоматически. Для кодирования знаков &, ", <, > и ' внутри значений, необходимо предварительно вызывать функцию EncodeXMLString. Это сделано, чтобы не происходила путаница, когда в определенных атрибутах (типа XML.Value система кодировала бы текст), а в других (к примеру, XML.Text или XML.Attributes) -- нет. Кроме того, это позволяет использование апострофов (') вместо двойных кавычек (") при задании значений атрибутов.

Важно: Здесь и далее понятие "тег" или "нода" обозначается словом "ветка". Структура документа XML часто называется деревом.

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

  • Использование подчиненных объектов для обхода дерева структуры XML.
  • Добавление и удаление веток.
  • Перенос ветвей относительно друг друга.
  • Работа с атрибутами веток.
  • Работа с пространствами имен.
  • Возможность одновременно изменять объект и обходить его структуру (локальные изменения объекта не приводят к пересчету всего дерева XML).

Программно объект может быть объектом XML -- т.е. структурой не указывающей на определенную ветку и отвечающей за весь документ в целом, а также объектом ветки XML, появляющимся во время обхода по веткам документа. Последний объект позволяет продолжить обход, добавить дочернюю ветку, удалить адресуемую ветку и т.п. Объект ветки, указывающий на корневую ветку документа считается непозиционированным. Такой объект не указывает на реальную ветку документа, не может содержать атрибутов, его нельзя удалить (из документа), и он может иметь только подчиненные ветки. Если объект ветки указывает на ветку, которая была удалена из XML-документа, он называется осиротевшим. Такие объекты не позволяют использовать функции обхода или изменения документа и чаще всего указывают на наличие ошибки в программном коде, либо возникают при сложном многопоточном взаимодействии с XML-документом.

Кроме обычных веток, объект также различает особенные. Особенные ветки никогда не содержат закрывающегося тега и могут быть двух типов:

  1. <?Имя ветки ...>. Используется для системных обозначений. Многие XML документы имеют ветку ?xml, следующую первой строкой текста. Также могут встречаться ветки ?php и пр. Нужно понимать, что название ветки в данном случае включает первый вопросительный знак. Атрибуты ветки могут не иметь стандартного формата.
  2. <!...>. Используется для комментариев и другой информации, заданной в произвольном формате. Часто используемые ветки: <![CDATA[ .. ]]>, <!DOCTYPE ...>, <!-- .. -->.

Особенные ветки имеют некоторые ограничения при работе с ними: нельзя получить или изменить их значения и изменить их атрибуты (так как они часто имеют произвольный формат). Для получения содержимого ветки необходимо использовать атрибут Attributes, отдающий все содержимое, кроме имени ветки и знаков ее начала и конца, либо атрибут Text, возвращающий все содержимое. Для изменения содержимого ветки необходимо записать ее новое значение в атрибут Text. Изменение веток таким способом может быть замедленно для больших файлов.

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


Ниже дается пример загрузки и обхода файла "c:\file.xml" для лучшего понимания возможностей объекта:


  //Рекурсивная функция вывода и обхода
  Function ВывестиДеревоФайла(аВетка,Стр="")
    //Если следующей ветки нет, переменная будет равна нулю
    While Not IsEmpty(аВетка) Do
      //Вывод имени ветки, значения (если нет вложенных веток) и полного пути ветки
      Message(Стр+аВетка.FullName+?(_And(аВетка.Count()=0,аВетка.Value<>"")," ---> """+аВетка.Value+"""")+", Путь: "+аВетка.Path);
      //Вызов функции для вложенных веток
      ВывестиДеревоФайла(аВетка.FirstChild(),Стр+"  ");
      //Найти следующую ветку на текущем уровне
      аВетка:=аВетка.Next();
    EndDo;
  EndFunction

аОб:=XML.create();
Стр:=аОб.LoadFromFile("c:\file.xml",65001);
If IsEmpty(Стр) Then
  //Вызов рекурсивного вывода дерева загруженного файла XML
  ВывестиДеревоФайла(аОб.FirstChild());
Else
  Message("Найдены ошибки при загрузке файла:"+_NEWLINE+Стр);
EndIf;

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

аОб:=XML.Create();
аОб.Text:="<?xml version=""1.0"" encoding=""utf-8""?>";
a:=аОб.AddNode("PublicInputSettings",,"xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""");
a:=a.AddNode("Keyboard");
Стр:="Move forward:W,Move backward:S,Strafe left:Q,Strafe right:E,Run:LeftShift,Crouch:Z";
While Стр<>"" Do
  Стр2:=TearStr(Стр,",");
  b:=a.AddNode("Entry");
  b.AddNode("Key",TearStr(Стр2,":"));
  b.AddNode("Value",Стр2);
EndDo;

Message("Текст результата:"+_NEWLINE+аОб.Text);
аОб.StoreToFile("c:\file.xml",65001,0);


Функции и атрибуты объекта

Идентификатор Статус Тип Визуальная Параметры Описание
Create Реализована Функция XML.Create():<Объект XML (XML)> Создает новый XML-объект.
LoadFromFile Реализована Функция XML.LoadFromFile(<Имя файла (STRING)>,<Кодовая страница (INT)>=-1):<Ошибки при загрузке файла (STRING)> Загружает XML-объект из файла, если файл содержит ошибки форматирования, загрузка будет остановлена и функция возвратит список ошибок в виде строки со знаками переноса на другую строку.
LoadFromString Реализована Функция XML.LoadFromString(<Строка с XML (STRING)>):<Ошибки при загрузке строки (STRING)> Загружает XML-объект из строки, если строка содержит ошибки форматирования, загрузка будет остановлена и функция возвратит список ошибок в виде строки со знаками переноса на другую строку.
Namespaces Планируется Функция XML.Namespaces():<Список пространств имен и ссылки на их схемы (LIST)> Функция находит и возвращает все пространства имен и URL их схем, использующиеся в XML-объекте. URL возвращаются в значениях списка, имена пространств имен -- в наименованиях списка. После загрузки соответствующих схем, их можно передать в виде списка функции Validate для проверки корректности структуры XML-объекта.
Validate Планируется Функция XML.Validate(<Имена файлов или XML-объекты схем проверки формата (LIST)>,<Ошибки при проверке (STRING)>,<Предупреждения при проверке (STRING)>):<Успешная проверка 1 иначе 0 (INT)> Функция проверяет корректность структуры файла из файлов схемы. При этом значения списка могут быть имена файлов (строки) или уже загруженные XML-объекты схемы, а именами списка должны быть наименования пространств имен. При наличии ошибок структуры, функция заполняет переменную второго или третьего аргумента.
StoreToFile Реализована Функция XML.StoreToFile(<Имя файла (STRING)>,<Кодовая страница (INT)>=0,<Добавить BOM (INT)>=0) Функция сохраняет текущий XML-объект в файл в требуемой кодовой странице, при этом в файл можно добавить BOM.
XML Реализована Атрибут XML.XML:<Объект XML (XML)> Атрибут используется совместно с объектом ветви XML, чтобы возвратить исходный объект XML.
Root Реализована Атрибут XML.Root:<Корневая ветка XML (XMLBRANCH)> Атрибут используется совместно с объектом XML или объектом ветки XML и возвращает корневую ветку XML.
Parent Реализована Атрибут XML.Parent:<Родительская ветка XML (XMLBRANCH)> Атрибут используется совместно с объектом XML или объектом ветки XML и возвращает родительскую ветку XML относительно текущей. Для корневой ветки будет возвращена она сама.
IsRoot Реализована Атрибут XML.IsRoot:<Является ли текущая ветка корневой (INT)> Атрибут используется совместно с объектом ветки XML и возвращает 1, если ветка является корневой, иначе возвращается 0.
Selected Реализована Функция XML.Selected():<Статус текущей ветки XML (INT)> Атрибут используется совместно с объектом XML или объектом ветки XML и возвращает 1, если объект указывает на какую-либо ветку XML, кроме корневой; 0 -- если объект указывает на корневую ветку и -1 -- если объект указывает на ветку, не привязанную более к объекту XML (осиротевшую ветку).
Path Реализована Атрибут XML.Path:<Полный путь текущей ветки XML (STRING)> Атрибут используется совместно с объектом ветки XML и возвращает или изменяет полный путь внутри XML-документа. Путь записывается в виде последовательности наименований веток с возможным дополнительным номером, указывающим на индекс ветки среди веток текущего уровня с таким же наименованием: <Ветка1>{[<Индекс1>]}{<Ветка2>...} (к примеру <Setup><Options><Option>[2]). При изменении атрибута будет осуществлена попытка перепозиционирования объекта.
Name Реализована Атрибут XML.Name:<Имя текущей ветки XML без пространства имен (STRING)> Атрибут используется совместно с объектом ветки XML и возвращает или изменяет наименование ветки в XML-документе. Наименования веток XML не могут содержать следующие знаки: !"#$%&'()*+,/;<=>?@[\]^`{
NameSpace Реализована Атрибут XML.NameSpace:<Пространство имен текущей ветки XML (STRING)> Атрибут используется совместно с объектом ветки XML и возвращает или изменяет наименование пространства имен ветки в XML-документе. При наличии пространств имен в документе, имена веток или атрибутов имеют формат {<Имя пространства имен>:}<Имя ветки или атрибута>. Для удаления пространства имен, атрибут следует инициализировать пустой строкой. Наименования пространства имен веток XML не могут содержать следующие знаки: !"#$%&'()*+,/;<=>?@[\]^`{
FullName Реализована Атрибут XML.FullName:<Имя текущей ветки XML с пространством имен (STRING)> Атрибут используется совместно с объектом ветки XML и возвращает или изменяет полное имя ветки (т.е., одновременно имя ветки и имя пространства имен ветки, если таковое присутствует) в XML-документе. При наличии пространств имен в документе, имена веток или атрибутов имеют формат {<Имя пространства имен>:}<Имя ветки или атрибута>. Наименования имен веток XML не могут содержать следующие знаки: !"#$%&'()*+,/;<=>?@[\]^`{
Value Реализована Атрибут XML.Value:<Значение текущей ветки XML (STRING)> Атрибут используется совместно с объектом ветки XML и возвращает или изменяет значение ветки (т.е. текст заключенный в объявления ветки: <Имя ветки>Значение ветки</Имя ветки>). Для веток, содержащих дочерние, возвращаемое значение также содержит дочерние объявления веток. При изменении значения допускается использование дочерних веток внутри устанавливаемого значения.
Text Реализована Атрибут XML.Text:<Часть текста XML, описывающего текущую ветку XML (STRING)> Атрибут используется совместно с объектом XML или объектом ветки XML и возвращает или изменяет полный текст объявления ветки (т.е. следующий текст: <Имя ветки [атрибуты ветки]>Значение ветки</Имя ветки>). Атрибут возвращает или изменяет полную структуру объявления. При использовании атрибута совместно с самим объектом XML, возвращается или изменяется полный текст документа.
Attributes Реализована Атрибут XML.Attributes:<Необработанные атрибуты текущей ветки XML (STRING)> Атрибут используется совместно с объектом ветки XML и возвращает или изменяет атрибуты ветки (т.е.: <Имя ветки [Атрибуты ветки]>Значение ветки</Имя ветки>). Атрибуты ветки имеют формат <Атрибут1>="<Значение1>" {<Атрибут1>="<Значение1>"...}. Имя атрибута имеет ограничения, подобные ограничениям имени ветки. Имя атрибута может также содержать имя пространства имен. Два атрибута с одинаковыми именами (и пространствами имен) не разрешается использовать для одной и той же ветки. При задании атрибутов, будет проверен их формат, при некорректном формате, будет вызвано исключение.
DoesExist Реализована Функция XML.DoesExist(<Путь XML относительный к текущему объекту (STRING)>):<Существует ли путь (INT)> Функция используется совместно с объектом XML или объектом ветки XML и проверяет, существует ли указанный путь для дочерних веток текущей. Путь записывается в виде последовательности наименований веток с возможным дополнительным номером, указывающим на индекс ветки среди веток текущего уровня с таким же наименованием: <Ветка1>{[<Индекс1>]}{<Ветка2>...} (к примеру <Setup><Options><Option>[2]).
CreatePath Реализована Функция XML.CreatePath(<Путь XML относительный к текущему объекту (STRING)>,<Использовать форматирование (INT)>=1):<Объект созданной ветки (XMLBRANCH)> Функция используется совместно с объектом XML или объектом ветки XML и создает указанный путь для дочерних веток текущей, если он до этого не существовал. Путь записывается в виде последовательности наименований веток, дополнительные индексы при этом не допускаются: <Ветка1>{<Ветка2>...} (к примеру <Setup><Options><Option>). Функция возвращает объект ветки, позиционированный на ветке в конце создаваемого пути.
Index Реализована Атрибут XML.Index:<Индекс текущей ветки относительно ее родителя (INT)> Атрибут используется совместно с объектом ветки XML и возвращает или изменяет индекс ветки относительно веток-соседей, принадлежащий одному родителю. Индексирование начинается с единицы.
Level Реализована Атрибут XML.Level:<Уровень текущей ветки относительно всего дерева XML (INT)> Атрибут используется совместно с объектом ветки XML и возвращает уровень вложения ветки в структуре XML-документа. Ветки, подчиненные корневой имеют уровень 1, ветки подчиненные им, имеют индекс 2 и т.д. Для корневой ветки или веток-сирот возвращается 0.
AddNode Реализована Функция XML.AddNode(<Имя ветки с пространством имен (STRING)>,<Значение ветки (STRING)>,<Атрибуты ветки (STRING)>="",<Использовать форматирование (INT)>=1):<Объект добавленной ветки (XMLBRANCH)> Функция позволяет добавить новую ветку как последнюю подчиненную ветку текущей. Для ветки задается полное имя, значение, атрибуты, если они необходимы. Также по умолчанию производится текстовое форматирование. Значение ветки может содержать подчиненные ветки.
Count Реализована Функция XML.Count():<Количество веток, вложенных в текущий объект (INT)> Функция используется совместно с объектом ветки XML и возвращает количество подчиненных ей веток.
ByIndex Реализована Функция XML.ByIndex(<Индекс вложенной ветки (INT)>):<Объект вложенной ветки (XMLBRANCH)> Функция используется совместно с объектом XML или объектом ветки XML и возвращает объект подчиненной ветки по ее индексу. Индексирование начинается с единицы.
ByName Реализована Функция XML.ByName(<Имя ветки с или без пространства имен (STRING)>,<Индекс среди одинаковых имен (INT)>=1):<Объект вложенной ветки (XMLBRANCH)> Функция используется совместно с объектом XML или объектом ветки XML и возвращает объект подчиненной ветки по ее имени. Наименования веток ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется ветка с любым пространством имен с совпадающим именем. Чтобы форсировать поиск веток без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя ветки>).
First Реализована Функция XML.First(<Имя ветки с или без пространства имен (STRING)>=""):<Первая ветка текущего уровня или ноль (XMLBRANCH,INT)> Функция используется совместно с объектом ветки XML и возвращает объект первой ветки, подчиненной родителю текущей ветки, имеющей заданное имя, если это необходимо. Наименования веток ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется ветка с любым пространством имен с совпадающим именем. Чтобы форсировать поиск веток без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя ветки>). Если ветка не найдена, функция возвращает ноль.
Last Реализована Функция XML.Last(<Имя ветки с или без пространства имен (STRING)>=""):<Последняя ветка текущего уровня или ноль (XMLBRANCH,INT)> Функция используется совместно с объектом ветки XML и возвращает объект последней ветки, подчиненной родителю текущей ветки, имеющей заданное имя, если это необходимо. Наименования веток ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется ветка с любым пространством имен с совпадающим именем. Чтобы форсировать поиск веток без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя ветки>). Если ветка не найдена, функция возвращает ноль.
Next Реализована Функция XML.Next(<Имя ветки с или без пространства имен (STRING)>=""):<Следующая ветка, относительно текущей или ноль (XMLBRANCH,INT)> Функция используется совместно с объектом ветки XML и возвращает объект ветки, подчиненной родителю текущей ветки, следующей непосредственно за текущей и имеющей заданное имя, если это необходимо. Наименования веток ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется ветка с любым пространством имен с совпадающим именем. Чтобы форсировать поиск веток без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя ветки>). Если ветка не найдена, функция возвращает ноль.
Prev Реализована Функция XML.Prev(<Имя ветки с или без пространства имен (STRING)>=""):<Предыдущая ветка, относительно текущей или ноль (XMLBRANCH,INT)> Функция используется совместно с объектом ветки XML и возвращает объект ветки, подчиненной родителю текущей ветки, следующей непосредственно перед текущей и имеющей заданное имя, если это необходимо. Наименования веток ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется ветка с любым пространством имен с совпадающим именем. Чтобы форсировать поиск веток без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя ветки>). Если ветка не найдена, функция возвращает ноль.
FirstChild Реализована Функция XML.FirstChild(<Имя ветки с или без пространства имен (STRING)>=""):<Первая ветка, вложенная в текущий объект или ноль (XMLBRANCH,INT)> Функция используется совместно с объектом XML или объектом ветки XML и возвращает объект первой ветки, подчиненной текущей ветке и имеющей заданное имя, если это необходимо. Наименования веток ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется ветка с любым пространством имен с совпадающим именем. Чтобы форсировать поиск веток без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя ветки>). Если ветка не найдена, функция возвращает ноль.
LastChild Реализована Функция XML.LastChild(<Имя ветки с или без пространства имен (STRING)>=""):<Последняя ветка, вложенная в текущий объект или ноль (XMLBRANCH,INT)> Функция используется совместно с объектом XML или объектом ветки XML и возвращает объект последней ветки, подчиненной текущей ветке и имеющей заданное имя, если это необходимо. Наименование веток ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется ветка с любым пространством имен с совпадающим именем. Чтобы форсировать поиск веток без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя ветки>). Если ветка не найдена, функция возвращает ноль.
Delete Реализована Функция XML.Delete(<Сохранить форматирование (INT)>=1) Функция используется совместно с объектом ветки XML и выполняет удаление текущей ветки и всех ее подчиненных веток из XML-документа. По умолчанию также сохраняется текстовое форматирование.
Duplicate Реализована Функция XML.Duplicate():<Объект, указывающий на ту же ветку, что и текущий (XMLBRANCH)> Функция используется совместно с объектом ветки XML и возвращает новый объект, позиционированный на ту же самую ветку, что и исходный.
AttributesCount Реализована Функция XML.AttributesCount():<Количество атрибутов текущей ветки (INT)> Функция используется совместно с объектом ветки XML и возвращает количество атрибутов текущей ветки.
GetAttributeName Реализована Функция XML.GetAttributeName(<Индекс атрибута (INT)><Возвратить с пространством имен (INT)>=0):<Имя адресуемого атрибута (STRING)> Функция используется совместно с объектом ветки XML и возвращает имя атрибута текущей ветки по его индексу. По умолчанию, пространство имен исключается из имени.
GetAttributeValue Реализована Функция XML.GetAttributeValue(<Индекс или имя атрибута с или без пространства имен (INT,STRING)>):<Значение адресуемого атрибута (STRING)> Функция используется совместно с объектом ветки XML и возвращает значение атрибута текущей ветки по его индексу или наименованию. Наименования атрибутов ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется атрибут с любым пространством имен с совпадающим именем. Чтобы форсировать поиск атрибутов без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя атрибута>). Если атрибут не найден, будет вызвано исключение.
SetAttributeValue Реализована Функция XML.SetAttributeValue(<Индекс или имя атрибута с или без пространства имен (INT,STRING)>,<Значение атрибута (STRING)>) Функция используется совместно с объектом ветки XML и изменяет значение атрибута текущей ветки по его индексу или наименованию. Наименования атрибутов ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется атрибут с любым пространством имен с совпадающим именем. Чтобы форсировать поиск атрибутов без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя атрибута>). Если атрибут не найден, будет вызвано исключение.
AddAttribute Реализована Функция XML.AddAttribute(<Имя атрибута с пространством имен (STRING)>,<Значение атрибута (STRING)>) Функция используется совместно с объектом ветки XML и добавляет новый атрибут в конец списка атрибутов текущей ветки. Для атрибута указывается его полное имя и значение.
DeleteAttribute Реализована Функция XML.DeleteAttribute(<Индекс или имя атрибута с или без пространства имен (INT,STRING)>) Функция используется совместно с объектом ветки XML и удаляет атрибут из списка атрибутов текущей ветки по его индексу или наименованию. Наименования атрибутов ищутся с учетом регистра. Если в искомом имени не задано пространство имен, ищется атрибут с любым пространством имен с совпадающим именем. Чтобы форсировать поиск атрибутов без пространств имен в этом случае, необходимо указать в искомом имени пустое пространство имен (:<Имя атрибута>). Если атрибут не найден, будет вызвано исключение.
DeleteAttributes Реализована Функция XML.DeleteAttributes() Функция используется совместно с объектом ветки XML и удаляет все атрибуты текущей ветки.