Created
December 25, 2011 22:46
-
-
Save hakre/1519893 to your computer and use it in GitHub Desktop.
Dump XML as Tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Dump XML (DOMNode) as Tree. | |
* | |
* @author hakre <http://hakre.wordpress.com/> | |
* @link http://stackoverflow.com/q/684227/367456 | |
* @link http://stackoverflow.com/q/12108324/367456 | |
*/ | |
abstract class IteratorDecoratorStub implements OuterIterator | |
{ | |
private $iterator; | |
public function __construct(Iterator $iterator) | |
{ | |
$this->iterator = $iterator; | |
} | |
public function getInnerIterator() | |
{ | |
return $this->iterator; | |
} | |
public function rewind() | |
{ | |
$this->iterator->rewind(); | |
} | |
public function valid() | |
{ | |
return $this->iterator->valid(); | |
} | |
public function current() | |
{ | |
return $this->iterator->current(); | |
} | |
public function key() | |
{ | |
return $this->iterator->key(); | |
} | |
public function next() | |
{ | |
$this->iterator->next(); | |
} | |
} | |
abstract class RecursiveIteratorDecoratorStub extends IteratorDecoratorStub implements RecursiveIterator | |
{ | |
public function __construct(RecursiveIterator $iterator) | |
{ | |
parent::__construct($iterator); | |
} | |
public function hasChildren() | |
{ | |
return $this->getInnerIterator()->hasChildren(); | |
} | |
public function getChildren() | |
{ | |
return new static($this->getInnerIterator()->getChildren()); | |
} | |
} | |
class DOMIterator extends IteratorDecoratorStub | |
{ | |
public function __construct($nodeOrNodes) | |
{ | |
if ($nodeOrNodes instanceof DOMNode) | |
{ | |
$nodeOrNodes = array($nodeOrNodes); | |
} | |
elseif ($nodeOrNodes instanceof DOMNodeList) | |
{ | |
$nodeOrNodes = new IteratorIterator($nodeOrNodes); | |
} | |
if (is_array($nodeOrNodes)) | |
{ | |
$nodeOrNodes = new ArrayIterator($nodeOrNodes); | |
} | |
if (! $nodeOrNodes instanceof Iterator) | |
{ | |
throw new InvalidArgumentException('Not an array, DOMNode or DOMNodeList given.'); | |
} | |
parent::__construct($nodeOrNodes); | |
} | |
} | |
class DOMRecursiveIterator extends DOMIterator implements RecursiveIterator | |
{ | |
public function hasChildren() | |
{ | |
return $this->current()->hasChildNodes(); | |
} | |
public function getChildren() | |
{ | |
$children = $this->current()->childNodes; | |
return new self($children); | |
} | |
} | |
class DOMRecursiveDecoratorStringAsCurrent extends RecursiveIteratorDecoratorStub | |
{ | |
public function current() | |
{ | |
$node = parent::current(); | |
$nodeType = $node->nodeType; | |
switch($nodeType) | |
{ | |
case XML_ELEMENT_NODE: | |
return "<$node->tagName>"; | |
case XML_TEXT_NODE: | |
return $node->nodeValue; | |
default: | |
return sprintf('(%d) %s', $nodeType, $node->nodeValue); | |
} | |
} | |
} | |
function xmltree_dump(DOMNode $node) | |
{ | |
$iterator = new DOMRecursiveIterator($node); | |
$decorated = new DOMRecursiveDecoratorStringAsCurrent($iterator); | |
$tree = new RecursiveTreeIterator($decorated); | |
foreach($tree as $key => $value) | |
{ | |
echo $value . "\n"; | |
} | |
} |
FIX: File was not PHP
IMP: Hyperlink to related SO question
@hakre, nice work. But you could also just do this:
print_r(json_decode(json_encode($node)));
@xeoncross: Depends on the level of verbosity you aim for, the other alternative is PHP 5.4.3 which offers improved var_dump for DOMDocument
and DOMElement
.
Related (updated) gist is: https://gist.github.com/3449600
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FIX: Make the recursive-decorator implementation not needed to re-implement the abstract getChildren decoration (requires PHP 5.3 then because of the static keyword).