XML
XML — текстовый формат, в котором пользовательские теги образуют дерево структурированных данных. Рассматриваются синтаксис, схемы, аннотации PASCAL VOC и сравнение с JSON и YAML.
XML (расширяемый язык разметки) — это текстовый формат структурированных данных, в котором пользовательские теги вкладываются друг в друга, образуя дерево. Например, элемент <size> может содержать элементы <width> и <height>. В феврале 1998 года Консорциум Всемирной паутины опубликовал XML 1.0 как Рекомендацию — упрощённое подмножество SGML (стандартного обобщённого языка разметки) для обмена документами и данными в интернете. В отличие от HTML, у XML нет предопределённых тегов: каждое приложение задаёт собственные теги для описания смысла данных. Поэтому на XML основано множество форматов файлов — от графики SVG и каналов RSS до документов Microsoft Office. В машинном обучении и компьютерном зрении XML встречается главным образом в файлах разметки, файлах моделей и системах здравоохранения и предприятий, предоставляющих обучающие данные.
Синтаксис и проверка XML#
Документ XML содержит ровно один корневой элемент. Элементы могут содержать текст, дочерние элементы и атрибуты внутри открывающего тега, как в <box label="car" xtl="10">. Пространства имён, объявленные с помощью xmlns, позволяют разделить теги из разных словарей. Документ считается корректно сформированным, если соблюдены правила синтаксиса: все теги закрыты, элементы правильно вложены, значения атрибутов заключены в кавычки. При первой же ошибке корректности парсеры должны остановить обработку. Документ также считается допустимым, если он соответствует схеме — определению типа документа (DTD) или XML Schema (XSD), где перечислены разрешённые элементы, их порядок и типы данных. Выражения XPath, например size/width, выбирают узлы дерева, а таблицы стилей XSLT преобразуют один словарь XML в другой.
XML в компьютерном зрении и машинном обучении#
Конкурс PASCAL VOC, проводившийся с 2005 по 2012 год, сделал XML классическим форматом разметки для обнаружения объектов. Для каждого изображения создаётся один XML-файл с именем и размером файла, а также элементом <object> для каждого объекта. В нём указываются название класса, флаги truncated и difficult, а также элемент <bndbox>, пиксельные координаты углов которого — xmin, ymin, xmax и ymax — задают ограничивающую рамку. Инструмент разметки LabelImg по умолчанию сохраняет данные в этом формате, поэтому многие наборы данных до сих пор поставляются с ним, и при предобработке данных их приходится преобразовывать. При экспорте из CVAT в формате CVAT for images 1.1 все аннотации задачи сохраняются в одном XML-файле, а координаты рамок записываются в атрибутах, например xtl, ytl, xbr и ybr.
XML также используют для описания моделей и записей. Промежуточное представление OpenVINO от Intel хранит слои и связи сети в файле .xml, а веса — в соответствующем файле .bin. Предварительно обученные каскадные детекторы лиц Haar из OpenCV тоже распространяются в формате XML. Медицинские записи HL7 FHIR, которые проекты клинического ИИ объединяют с изображениями для анализа медицинских изображений, можно передавать в формате XML или JSON. Файлы Word и Excel представляют собой ZIP-архивы с частями XML, которые считывают системы документирования ИИ.
В этом примере с помощью встроенного в Python модуля ElementTree разбирается аннотация VOC, а координаты каждой рамки преобразуются в нормализованные значения центра, ширины и высоты для формата меток YOLO:
import xml.etree.ElementTree as ET
# A PASCAL VOC annotation: one XML file per image, one <object> per box
voc = """
<annotation>
<filename>000017.jpg</filename>
<size><width>480</width><height>364</height><depth>3</depth></size>
<object><name>person</name><difficult>0</difficult>
<bndbox><xmin>185</xmin><ymin>62</ymin><xmax>279</xmax><ymax>199</ymax></bndbox></object>
<object><name>horse</name><difficult>0</difficult>
<bndbox><xmin>90</xmin><ymin>78</ymin><xmax>403</xmax><ymax>336</ymax></bndbox></object>
</annotation>
"""
root = ET.fromstring(voc)
w, h = int(root.find("size/width").text), int(root.find("size/height").text)
# Convert corner pixels to YOLO's normalized center x, center y, width, height
for obj in root.iter("object"):
box = obj.find("bndbox")
x1, y1, x2, y2 = (float(box.find(k).text) for k in ("xmin", "ymin", "xmax", "ymax"))
cx, cy = ((x1 + x2) / 2 - 1) / w, ((y1 + y2) / 2 - 1) / h # VOC pixel indices start at 1
print(obj.find("name").text, f"{cx:.3f} {cy:.3f} {(x2 - x1) / w:.3f} {(y2 - y1) / h:.3f}")Вывод содержит person 0.481 0.356 0.196 0.376 и horse 0.511 0.566 0.652 0.709: те же две рамки в виде долей от размера изображения, готовые к записи в строки меток после индексов классов. Файл набора данных Ultralytics VOC.yaml выполняет это преобразование автоматически при первом использовании: скачивает VOC 2007 и 2012, разбирает каждую XML-аннотацию с помощью ElementTree, пропускает объекты с флагом difficult и записывает метки YOLO .txt для 16 551 обучающего и 4 952 валидационных изображений.
XML, JSON и YAML#
- JSON: объекты, массивы, строки, числа и логические значения в более лаконичном формате, чем XML, с прямым отображением на словари Python и объекты JavaScript. Его используют веб-API и аннотации набора данных COCO.
- YAML: вместо закрывающих тегов используются отступы; формат поддерживает комментарии и начиная с YAML 1.2 принимает любой документ JSON. Поэтому YAML популярен для конфигураций, которые редактируют вручную, например файлов наборов данных и моделей YOLO.
- XML: более многословный формат со схемами, пространствами имён, атрибутами и смешанным содержимым — текстом со встроенной разметкой. Он подходит для документов и стандартов, требующих строгой проверки.
Разбор непроверенного XML#
Механизм сущностей XML позволяет документу определять повторно используемый текст, чем пользуются злоумышленники. При атаке «миллиард смехов» около десяти вложенных определений сущностей, каждое из которых десять раз ссылается на предыдущее, раздувают файл размером в несколько сотен байт до гигабайтов текста. При атаке с внешней сущностью XML (XXE) объявляется сущность, указывающая на локальный файл или внутренний URL. Уязвимый парсер может прочитать секретные данные в документ или отправить запросы из внутренней сети. xml.etree.ElementTree в Python не раскрывает внешние сущности и при их обнаружении выдаёт ошибку разбора, а парсер Expat защищён от атаки «миллиард смехов» начиная с версии 2.4.1. Пакет defusedxml обеспечивает дополнительную защиту и выдаёт EntitiesForbidden при любом объявлении сущности — внутренней или внешней.










