
XML
XML — текстовый формат, предназначенный для хранения структурированных данных (взамен существующих файлов баз данных), для обмена информацией между программами, а также для создания на его основе более специализированных языков разметки (например, XHTML), иногда называемых словарями. XML является упрощённым подмножеством языка SGML.
XML это удобная штука хранить файлы в читаемом виде.
Например простой XML файл может быть таким
<?xml version="1.0" encoding="UTF-8"?> <root> <data> <row> <id>1</id> <name company="ibm" status="banned" >Vasilii</name> <age>18</age> </row> <row> <id>2</id> <name company="ibm">Anton</name> <age>20</age> </row> <row> <id>3</id> <name company="apple">Petro</name> <age>35</age> </row> </data> </root>
На данном файле будет показана работа с XPath.
Как видно из примера XML удобен тем, что он легко читаем, структурирован. В данном формате удобно хранить данные, более того, существует множество библиотек по работе с данным типом файла.
Любой элемент имеет свой путь, например путь root-data-row[0] будет указывать на ветку Василия.
Но когда программист начинает использовать данный файл у него возникает проблем с манипуляцией файла. Например необходимо выбрать всех людей у которых возраст < 20.
Что делать?
Решением данной проблемы является XPath.
XPath это своебразный язык, ябы так сказал, язык запросов к документу XML который возвращает итератор на ветки удовлетворяющих условия.
Итак, есть документ.
Напишем РНР код для этого документа. В данном примере используются фукнции SimpleXML для работы.
Есть код:
$xml = simplexml_load_file("db.xml"); var_dump($xml);
Результат будет следующий:
object(SimpleXMLElement)[1] public 'data' => object(SimpleXMLElement)[2] public 'row' => array 0 => object(SimpleXMLElement)[3] public 'id' => string '1' (length=1) public 'name' => string 'Vasilii' (length=7) public 'age' => string '18' (length=2) 1 => object(SimpleXMLElement)[4] public 'id' => string '2' (length=1) public 'name' => string 'Anton' (length=5) public 'age' => string '20' (length=2) 2 => object(SimpleXMLElement)[5] public 'id' => string '3' (length=1) public 'name' => string 'Petro' (length=5) public 'age' => string '35' (length=2)
Как видно из результата доступ можно делать как: $xml->data->row[0]->name == Valilii.
Теперь собственно XPath.
XPath позволяет использовать условия и свои встроенные функции для выборки веток.
Например / (слеш) — указывает на иерархию веток, например /data,
Основные моменты при использовании:
/ — корневой узел
// — множество узлов удовлетворяющих след условие (детальнее на вики)
* — любые символы
@ — аттрибут
[] — аналог () в sql, задает условия
and, or — И, ИЛИ.
Более подробно написано ru.wikipedia.org/wiki/XPath
Сделаем выборку всех элементов с помощью XPath.
foreach( $xml->xpath("//row") as $res) var_dump($res);
object(SimpleXMLElement)[6] public 'id' => string '1' (length=1) public 'name' => string 'Vasilii' (length=7) public 'age' => string '18' (length=2) object(SimpleXMLElement)[7] public 'id' => string '2' (length=1) public 'name' => string 'Anton' (length=5) public 'age' => string '20' (length=2) object(SimpleXMLElement)[8] public 'id' => string '3' (length=1) public 'name' => string 'Petro' (length=5) public 'age' => string '35' (length=2)
Давайте сделаем выборку, где age>18
foreach( $xml->xpath("//row[age>18]") as $res) var_dump($res);
Результат:
object(SimpleXMLElement)[6] public 'id' => string '2' (length=1) public 'name' => string 'Anton' (length=5) public 'age' => string '20' (length=2) object(SimpleXMLElement)[7] public 'id' => string '3' (length=1) public 'name' => string 'Petro' (length=5) public 'age' => string '35' (length=2)
Сделаем выборку у всех у которых аттрибут company='ibm'
foreach( $xml->xpath("//row[name[@company='ibm']]") as $res) var_dump($res);
Результат:
object(SimpleXMLElement)[6] public 'id' => string '1' (length=1) public 'name' => string 'Vasilii' (length=7) public 'age' => string '18' (length=2) object(SimpleXMLElement)[7] public 'id' => string '2' (length=1) public 'name' => string 'Anton' (length=5) public 'age' => string '20' (length=2)
Следует обратить внимание, что атрибут @company является частью name, по этому просто написать row[ @company=..] — нельзя.
Сделаем выборку людей, у которых возраст больше 18 и работает в IBM
foreach($xml->xpath("//row[name[@company='ibm'] and age>18]") as $res) var_dump($res);
Результат:
object(SimpleXMLElement)[6] public 'id' => string '2' (length=1) public 'name' => string 'Anton' (length=5) public 'age' => string '20' (length=2)
Можно увидеть что комбинировать очень просто.
Следующий пример покажет как можно использовать встроенные функции, например
last() — получим последнего человека списка.
foreach($xml->xpath("//row[last()]") as $res) var_dump($res);
Результат:
object(SimpleXMLElement)[6] public 'id' => string '3' (length=1) public 'name' => string 'Petro' (length=5) public 'age' => string '35' (length=2)
А теперь найдем людей которые НЕ работают в IBM:
foreach( $xml->xpath("//row[name[not(@company='ibm')]]") as $res) var_dump($res);
Результат:
object(SimpleXMLElement)[6] public 'id' => string '3' (length=1) public 'name' => string 'Petro' (length=5) public 'age' => string '35' (length=2)
Все очень просто и удобно!
Результаты
Xpath — хороший инструмент для работы с документом XML. Базовые функции выполняет.
Для более сложных есть XQuery, но речь сейчас не об этом.
XML+XPath достойная замена в тех местах, где неудобно использовать БД по каким либо причинам.
Спасибо.
Продолжение следует.
Первоисточник