我想将一个函数应用于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片段?
答案 0 :(得分:11)
这里Standard PHP Library可以拯救。
一种选择是使用(鲜为人知的)SimpleXMLIterator
。它是PHP中可用的几个RecursiveIterator
之一,SPL中的RecursiveIteratorIterator
可用于循环并更改所有元素的文本。
$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>
答案 1 :(得分: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查询允许更多控制,例如命名空间。