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() を適用して 2 番目の XML スニペットを取得するにはどうすればよいですか?

4

2 に答える 2

11

ここで、標準 PHP ライブラリーが役に立ちます。

1 つのオプションは (ほとんど知られていない) を使用することSimpleXMLIteratorです。これはRecursiveIterator、PHP で使用できるいくつかの の1 つであり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 に答える