Более конкретный путь, чем $ DOMDocument-> gN; getNodePath ();

В настоящее время мне нужен путь XPath к элементу. Путь должен содержать атрибут, который однозначно идентифицирует каждый элемент на пути (в данном случае, атрибут name).

$DOMDocument->getNodePath(); возвращает путь, но без атрибутов. Атрибуты необходимы, так как XML будет немного меняться.

В настоящее время я пишу метод, чтобы вручную пройти и проверить каждый элемент в пути для атрибута имени, а затем вставить его в строку в соответствующей точке. Есть ли более легкий / быстрый / не такой хакерский способ сделать это?

0

Решение

Решение xsh из @choroba может быть переведено в исходный код PHP с помощью DOMXpath::evaluate():

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

foreach ($xpath->evaluate('//address') as $address) {
$path = '';
foreach ($xpath->evaluate('ancestor-or-self::*', $address) as $ancestor) {
$path .= '/'.$ancestor->nodeName;
if ($name = $ancestor->getAttribute('name')) {
$path .= '[@name = "'.$name.'"]';
}
}
var_dump($path);
}

ancestor-or-self::* является выражением Xpath, которое выбирает все узлы элемента, начиная с узла контекста и заканчивая элементом документа.

0

Другие решения

Вы можете использовать XPath для получения строки. Например, в XSH:

for //address {
for ancestor-or-self::*
echo :s :n '/'
name()
xsh:if(@name, concat('[@name="', @name, '"]'),'') ;
echo ;
}

Запустите его на следующем XML

<root>
<customers name="2014">
<customer name="John">
<address/>
</customer>
<customer name="Jane">
<address/>
</customer>
</customers>
<customers name="2015">
<customer name="Daniel">
<address/>
</customer>
<customer name="Dave">
<address/>
</customer>
</customers>
</root>

я собираюсь

/root/customers[@name="2014"]/customer[@name="John"]/address
/root/customers[@name="2014"]/customer[@name="Jane"]/address
/root/customers[@name="2015"]/customer[@name="Daniel"]/address
/root/customers[@name="2015"]/customer[@name="Dave"]/address
1

По вопросам рекламы [email protected]