«Случайный» доступ к дочерним элементам узла XML (с пространствами имен) в переполнении стека

Это мой первый пост о переполнении стека, и я должен сказать, что нашел этот сайт золотым притоком ответов!
Итак, первый пост немного нубистский — там много ответов примерно на эту тему, но, похоже, они не подходят под мою конкретную проблему. Код, который обращается к XML с использованием пространств имен, работает довольно аккуратно, поэтому может помочь любому, кто попытается выяснить, ЧТО вырвалось …

У меня есть XML-файл, который я читаю:

<?xml version='1.0'?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns:ext-domain="http://www.heartinternet.co.uk/whapi/ext-domain-2.4">
<response>
<result code='1000'>
<msg>Command completed successfully</msg>
</result>
<resData>
<domain:chkData>
<domain:cd>
<domain:name avail="1">foo.com</domain:name>
</domain:cd>
<domain:cd>
<domain:name avail="0">foo.net</domain:name>
<domain:reason>registered</domain:reason>
</domain:cd>
<domain:cd>
<domain:name avail="0">foo.org</domain:name>
<domain:reason>unknown</domain:reason>
</domain:cd>
<domain:cd>
<domain:name avail="0">foo.plumbing</domain:name>
<domain:reason>c:category7</domain:reason>
</domain:cd>
<domain:cd>
<domain:name avail="1">foo.uk</domain:name>
<domain:reason>qualified</domain:reason>
</domain:cd>
</domain:chkData>
</resData>
<extension>
<ext-domain:categorisedChkData>
<ext-domain:cd>
<ext-domain:name price="1050.37">foo.plumbing</ext-domain:name>
</ext-domain:cd>
</ext-domain:categorisedChkData>
</extension>
<trID>
<clTRID>6f2d7447511677c62631e4bdb9563172</clTRID>
<svTRID>test-da76f89aacec9861b89bf093fc120566</svTRID>
</trID>
</response>
</epp>

Я хочу, чтобы иметь возможность получить доступ к детям домена: CD.
Смотрите комментарии в коде ниже

$xml = simplexml_load_string($return_xml, NULL, NULL, "urn:ietf:params:xml:ns:epp-1.0");
$xml->registerXPathNamespace('domain', 'urn:ietf:params:xml:ns:domain-1.0');
$xml->registerXPathNamespace('ext-domain', 'http://www.heartinternet.co.uk/whapi/ext-domain-2.4');

// I can list out the domain:name elements and attributes nicely.
foreach ($xml->xpath('//domain:name') as $domain){
echo '<p>Domain: '.$domain.'<br/>';                 // Works
echo 'avail-code: '.$domain['avail'].'<br/>';       // Works
echo '</p>';
}

// And I can list out the domain:reason elements afterwards.
foreach ($xml->xpath('//domain:reason') as $reason){
echo '<p>Reason: '.$reason.'<br/>';                 // Works
echo '</p>';
}

// But what I want, is to be able to get to them both from the same node in the order I need them.
// A little like this, so that I can form some content.
$res = $xml->xpath('//domain:cd');
foreach ($res->children() as $node){
echo '<p>Name: '.$node['domain:name'].'<br/>';      // this is wrong, mind.
echo 'Reason: '.$node['domain:reason'].'<br/>';     // this is wrong, mind.
echo '</p>';
}

Кажется немного расточительным и трудоемким, чтобы запускать отдельные запросы xpath для получения каждого бита данных, я должен иметь доступ к дочерним узлам (домен: имя, домен: причина), но решение немного труднодостижимо, особенно с дополнительное усложнение пространств имен.

Спасибо, ребята. 🙂

0

Решение

Спасибо, Призрак.

Мне удалось придумать следующее, хотя это позволяет мне извлекать данные в произвольном порядке, а не последовательно.

$res = $xml->xpath('//domain:cd');
foreach ($res as $node){
$namespaces = $node->getNameSpaces(true);
$cd         = $node->children($namespaces['domain']);

echo '<p>'. $cd->name.'<br/>';
echo        $cd->reason.'</p>';
}

Бах, это всегда приходит к тебе сразу после того, как ты отправил вопрос на форуме, не так ли?

2

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

Других решений пока нет …