Iterating Multidimensional Arrays for XML Transformation
One common task when working with nested or multidimensional arrays is converting them into an XML structure. For instance, consider the following array:
$nodes = array( "parent node", "parent node", array( "child node", "child node", array( "grand child node", "grand child node" ) ) );
The goal is to transform the given array into an XML string, such as:
<node> <node>parent node</node> <node>parent node</node> <node> <node>child node</node> <node>child node</node> <node> <node>grand child node</node> <node>grand child node</node> </node> </node> </node>
Recursive Approach
A common method for handling nested structures is through recursion, as illustrated below:
<code class="php">function traverse($nodes) { echo "<node>"; foreach ($nodes as $node) { if (is_array($node)) { traverse($node); } else { echo "<node>$node</node>"; } } echo "</node>"; }</code>
Iterative Approach Using Iterator
However, an alternative approach is to use iteration with an Iterator. This allows for greater flexibility and simplifies the process:
<code class="php">class TranformArrayIterator extends RecursiveIteratorIterator { // Add indentation for each level protected function indent() { echo str_repeat("\t", $this->getDepth()); return $this; } public function beginIteration() { echo '<nodes>', PHP_EOL; } public function endIteration() { echo '</nodes>', PHP_EOL; } public function beginChildren() { $this->indent()->beginIteration(); } public function endChildren() { $this->indent()->endIteration(); } public function current() { return sprintf('%s<node>%s</node>%s', str_repeat("\t", $this->getDepth() + 1), parent::current(), PHP_EOL ); } }</code>
To use the iterator, instantiate it and traverse the array:
<code class="php">$iterator = new TranformArrayIterator(new RecursiveArrayIterator($nodes)); foreach ($iterator as $val) { echo $val; }</code>
This approach produces an equivalent XML output as the recursive method.
XMLWriter Collaboration
For more precise XML control and validation, you can utilize an XMLWriter in collaboration with the iterator:
<code class="php">class TranformArrayIterator extends RecursiveIteratorIterator { private $xmlWriter; public function __construct(XmlWriter $xmlWriter, Traversable $iterator, $mode = RecursiveIteratorIterator::LEAVES_ONLY, $flags = 0) { $this->xmlWriter = $xmlWriter; parent::__construct($iterator, $mode, $flags); } public function beginIteration() { $this->xmlWriter->startDocument('1.0', 'utf-8'); $this->beginChildren(); } public function endIteration() { $this->xmlWriter->endDocument(); } public function beginChildren() { $this->xmlWriter->startElement('nodes'); } public function endChildren() { $this->xmlWriter->endElement(); } public function current() { $this->xmlWriter->writeElement('node', parent::current()); } }</code>
This iterator gives finer control over the XML structure and ensures its validity.
By leveraging the power of iterators, you can efficiently process and transform multidimensional arrays into XML structures, offering both flexibility and control for a variety of scenarios.
The above is the detailed content of How to Iteratively Transform Multidimensional Arrays into XML with Iterator and XMLWriter. For more information, please follow other related articles on the PHP Chinese website!