<XML>¶
В общем выбор в те дни был предопределён - XML был сверхсовременным и суперудобным,
Сложность читаемости XML компенсируется простотой его программной обработки. Чёткая иерархическая структура, понятные начало, конец и значение. В том же питоне xmltodict изящно любой валидный XML разворачивает в словарь. А вообще вот годная статья про то, как предполагается работать с XML средствами стандартной библиотеки.
Давайте сначала на отвлечённом примере поразбираемся?
<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book> <title>Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <instock> </instock> </book> <book> <title>Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <instock /> </book> </bookstore>
Тут у нас XML, описывающий книжный магазин и имеющиеся в нём книги. У каждой книги есть свой набор атрибутов - название, автор, год выпуска, наличие в магазине.
Всё начинается с
XML Prolog¶
<?xml version="1.0" encoding="UTF-8"?>
Дерево элементов¶
root
, все последующие - его дети.<bookstore>
. Элемент представляет из себя открывающий и закрывающий теги и содержимое.<bookstore>
и <Bookstore>
- это разные теги.siblings
).<book>
. Разные элементы <book>
друг для друга являются собратьями.<book>
есть дочерние элементы. Их состав совсем не обязательно должен быть одинаковым - XML этого не требует, однако этого может (и скорее всего будет) требовать приложение.Главное правило XML - каждый открывшийся тег должен быть закрыт: сказал <a>
- говори и </a>
. Элемент может быть пустым, просто выражая факт своего существования, тогда запись <instock></instock>
можно заменить на просто <instock/>
.
Атрибуты¶
Взглянем на другой пример:
<bookstore> <book category="cooking"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> </book> <book category="children"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> </book> </bookstore>
category="cooking"
. Она описывает дополнительные данные об элементе. Своего рода метаданные.<book category="cooking"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> </book>
и
<book> <category>cooking</category> <title>Everyday Italian <lang>en</lang> </title> <author>Giada De Laurentiis</author> <year>2005</year> </book>
Чтобы далеко не уходить, вот пример из netconf:
<rpc message-id=”101″> <get-config> <source> <running/> </source> </get-config> </rpc>
message-id
- это атрибут элемента RPC, который не имеет непосредственного отношения к передаваемым далее данным, но позволяет отследить по message-id
ответ сервера (он вставит его в <rpc-reply>
).<interfaces operation="replace">
. Атрибут operation="replace"
не является частью конфигурации интерфейса, он лишь говорит, что то, что существует сейчас на коробке в ветке <interfaces>
, нужно заменить на то, что описано в данном XML.Namespaces¶
<name>
может быть как у интерфейса, так и у пользователя и у влана итд. Их можно разнести в разные NS, хотя это не обязательно, потому что они находятся под разными родителями.<root> <address> <city> <name>Moscow</name> <street>Novocheremushkinskaya, 50</street> </city> </address> <address> <ipv6>2a01:ba80:e:20::32</ipv6> <ipv4>185.127.149.137</ipv4> </address> </root>
Прямо объявляем неймспейсы с префиксами:
<root> <postal:address xmlns:postal="https://www.linkmeup.ru/postal_address/"> <postal:city> <postal:name>Moscow</postal:name> <postal:street>Novocheremushkinskaya, 50</postal:street> </postal:city> </postal:address> <ip:address xmlns:ip="https://www.linkmeup.ru/ip/"> <ip:ipv6>2a01:ba80:e:20::32</ip:ipv6> <ip:ipv4>185.127.149.137</ip:ipv4> </ip:address> </root>
Теперь это полное, fully qualified, имя безо всяких ограничений. Обращаемся из приложений, соответственно, по полному имени.
postal
иip
- это короткие префиксы. Само имя namespace - это произвольная строка. Но негласная договорённость, что все используют URI. Он может вести на страницу с описанием этого неймспейса, а может и не вести. Но указание префикса в каждом теге может показаться не очень удобным, тогда есть второй способ.Определяем
default namespace
<root> <address xmlns="https://www.linkmeup.ru/postal_address/"> <city> <name>Moscow</name> <street>Novocheremushkinskaya, 50</street> </city> </address> <address xmlns="https://www.linkmeup.ru/ip/"> <ipv6>2a01:ba80:e:20::32</ipv6> <ipv4>185.127.149.137</ipv4> </address> </root>
Область действия дефолтного неймспейса - сам элемент и все его потомки, если он нигде не переопределяется.
Концепция namespace с одной стороны проста, с другой стороны и там есть место тёмным пятнам. Если хочется подетальнее изучить, то есть пара полезных FAQ про них.
Xpath - XML Path¶
XPath
- это способ выбрать ноды или множество нод из XML документа./
».Например, в XML из примера выше путь к элементу <title>
будет записан в виде /bookstore/book/title
sum
, count
, avg
, min
, starts-with
, contains
, concat
, true
, false
- над разными типами данных: числа, строки, булевы./bookstore/book[price>35]/title
XPath оперирует нодами, которыми являются элементы, атрибуты, текст, неймспейсы и другое.
- Вернуть BGP-группу, в которой есть peer 10.1.1.1
- Вернуть интерфейс, на котором число ошибок больше 100
- Вернуть список интерфейсов, на которых native-vlan 127
- Вернуть количество интерфейсов, в имени которых есть «Ethernet».
В контексте NETCONF вы можете его встретить, но это не самая популярная capability. В общем, знать про него полезно, но глубоко копать не будем. Если хочется поподробнее почитать, то это можно сделать например, тут.
Схема¶
<interface>
, а читать его пытаются из элемента <unit>
?YYYY-MM-DD
, а читать её пытаются в MM-DD-YYYY
(больные ублюдки).- двум сторонам использовать один и тот же способ хранения и распаковки данных.
- описывать содержимое документа
- определять ограничения на данные
- проверять корректность XML
Называется это хозяйство XML Schema Definition - или коротко XSD.
Поскольку это тот же самый XML, он должен как-то обозначать себя, что является схемой. Для этого есть ключевой элемент <schema>
. Вот так будет выглядеть XSD для кусочка XML выше:
<xs:schemaxmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:elementname="address"> <xs:complexType> <xs:sequence> <xs:elementname="country_name" type="xs:string"/> <xs:elementname="population" type="xs:decimal"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
При этом в самом XML можно дать ссылку на XSD
<note xmlns="https://www.linkmeup.ru" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.linkmeup.ru/404.xsd">
Самостоятельное продолжение изучения XSD.
Лучшая сторона XSD - это то, что на его основе можно автоматически генерировать объекты в языках программирования. То есть XSD описывает, какие именно объекты и структуры должны быть созданы, а конкретный XML - наполняет экземпляр, пользоваться которым значительно удобнее, чем крафтить XML. Со схемами и моделями мы будем разбираться дальше.
Надеюсь получилось, не утопая в деталях, дать понимание, что из себя представляет XML. Далее для нас это будет важным.
</XML>