4

我想对 SimpleXML 对象中的每个节点应用一个函数。

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

//函数reverseText($str){};

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

我如何将 reverseText() 应用于每个节点以获取第二个 XML 片段?

4

2 回答 2

11

在这里,标准 PHP 库可以提供帮助。

一种选择是使用 (鲜为人知) SimpleXMLIterator。它是RecursiveIteratorPHP 中可用的几个 s之一,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>
于 2013-06-13T19:46:17.080 回答
0

您可以使用该方法创建文档中所有节点的数组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 查询允许更多控制,例如使用命名空间。

于 2013-06-22T12:35:52.407 回答