PHP array_walk_recursive () для объектов SimpleXML?

Я хотел бы применить функцию к каждому узлу объекта SimpleXML.

<api> <stuff>ABC</stuff> <things> <thing>DEF</thing> <thing>GHI</thing> <thing>JKL</thing> </things> </api> 

// function reverseText ($ str) {};

 <api> <stuff>CBA</stuff> <things> <thing>FED</thing> <thing>IHG</thing> <thing>LKJ</thing> </things> </api> 

Как я применил бы reverseText () для каждого узла, чтобы получить второй фрагмент XML?

Здесь стандартная библиотека PHP может прийти на помощь.

Один из вариантов – использовать (малоизвестный) SimpleXMLIterator . Это один из нескольких RecursiveIterator доступных в PHP, и RecursiveIteratorIterator из SPL можно использовать для перебора и изменения текста всех элементов.

 $source = ' <api> <stuff>ABC</stuff> <things> <thing>DEF</thing> <thing>GHI</thing> <thing>JKL</thing> </things> </api> '; $xml = new SimpleXMLIterator($source); $iterator = new RecursiveIteratorIterator($xml); foreach ($iterator as $element) { // Use array-style syntax to write new text to the element $element[0] = strrev($element); } echo $xml->asXML(); 

Вышеприведенный пример выводит следующее:

 <?xml version="1.0"?> <api> <stuff>CBA</stuff> <things> <thing>FED</thing> <thing>IHG</thing> <thing>LKJ</thing> </things> </api> 

Вы можете создать массив всех узлов в документе с помощью SimpleXMLElement::xpath() .

Затем вы можете использовать array_walk в этом массиве. Однако вы не хотите изменять строку каждого узла, только те элементы, у которых нет дочерних элементов.

 $source = ' <api> <stuff>ABC</stuff> <things> <thing>DEF</thing> <thing>GHI</thing> <thing>JKL</thing> </things> </api> '; $xml = new SimpleXMLElement($source); array_walk($xml->xpath('//*'), function(&$node) { if (count($node)) return; $node[0] = strrev($node); }); echo $xml->asXML(); 

Вышеприведенный пример выводит следующее:

 <?xml version="1.0"?> <api> <stuff>CBA</stuff> <things> <thing>FED</thing> <thing>IHG</thing> <thing>LKJ</thing> </things> </api> 

Запрос xpath позволяет больше контролировать, например, с пространствами имен.