
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 достойная замена в тех местах, где неудобно использовать БД по каким либо причинам.
Спасибо.
Продолжение следует.
Первоисточник
