PHP array_walk_recursive() for SimpleXML objects?

混江龙づ霸主 提交于 2019-12-01 22:00:55

问题


I would like to apply a function to every node in a SimpleXML object.

<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>

How would I apply reverseText() to every node to get the second XML snippet?


回答1:


Here the Standard PHP Library can come to the rescue.

One option is to use the (little known) SimpleXMLIterator. It is one of several RecursiveIterators available in PHP and a RecursiveIteratorIterator from the SPL can be used to loop over and change all of the elements' text.

$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();

The above example outputs the following:

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



回答2:


You can create an array of all nodes in the document with the SimpleXMLElement::xpath() method.

Then you can use array_walk on that array. However you don't want to reverse the string of every node, only of those elements which don't have any child elements.

$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();

The above example outputs the following:

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

The xpath query allows more control for example with namespaces.



来源:https://stackoverflow.com/questions/17095484/php-array-walk-recursive-for-simplexml-objects

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!