Создание выражения Xpath:
- Выбор любого
subject
элемента
//subject
- ... с дочерним элементом
relation
//subject[relation]
- ... с атрибутом
role
с заданным текстом
//subject[relation/@role="ITSupporter"]
- ... и получением атрибута
@id
subject
//subject[relation/@role="ITSupporter"]/@id
Кроме того, источник может быть очищен.Массивы PHP могут использовать синтаксис $array[]
для вставки в них новых элементов.
Объединить:
$xml = <<<'XML'
<subject id="Tom">
<relation unit="ITSupport" role="ITSupporter" />
</subject>
XML;
$role = 'ITSupporter';
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$ids = [];
foreach ($xpath->evaluate("//subject[relation/@role='".$role."']/@id") as $idAttribute) {
$ids[] = $idAttribute->value;
}
var_dump($ids);
Вывод:
array(1) {
[0]=>
string(3) "Tom"
}
Если вы ожидаете толькоЕдинственный результат, который вы можете преобразовать в Xpath:
$id = $xpath->evaluate(
"string(//subject[relation/@role='".$role."']/@id)"
);
var_dump($id);
Вывод:
string(3) "Tom"
Пространства имен XML
Глядя на пример, размещенный в комментарии, ваш XML используетПространство имен http://cpee.org/ns/organisation/1.0
без префикса.Синтаксический анализатор XML разрешит его, поэтому вы можете прочитать узлы как {http://cpee.org/ns/organisation/1.0}subject
.Вот 3 примера, которые все приводят к этому:
то же самое должно случиться с выражением Xpath.Однако Xpath не имеет пространства имен по умолчанию.Вам необходимо зарегистрировать префикс по вашему выбору.Это позволяет механизму Xpath разрешать что-то вроде //org:subject
в //{http://cpee.org/ns/organisation/1.0}subject
.
PHP не нужно сильно менять:
$xml = <<<'XML'
<subject id="Tom" xmlns="http://cpee.org/ns/organisation/1.0">
<relation unit="ITSupport" role="ITSupporter" />
</subject>
XML;
$role = 'ITSupporter';
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
// register a prefix for the namespace
$xpath->registerNamespace('org', 'http://cpee.org/ns/organisation/1.0');
$ids = [];
// address the elements using the registered prefix
$idAttributes = $xpath->evaluate("//org:subject[org:relation/@role='".$role."']/@id");
foreach ($idAttributes as $idAttribute) {
$ids[] = $idAttribute->value;
}
var_dump($ids);