Skip to content

Instantly share code, notes, and snippets.

@hakre
Created December 25, 2011 22:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hakre/1519893 to your computer and use it in GitHub Desktop.
Save hakre/1519893 to your computer and use it in GitHub Desktop.
Dump XML as Tree
<?php
/*
* Dump XML (DOMNode) as Tree.
*
* @link http://stackoverflow.com/q/684227/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";
}
}
@hakre
Copy link
Author

hakre commented Dec 25, 2011

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).

@hakre
Copy link
Author

hakre commented Dec 25, 2011

FIX: File was not PHP
IMP: Hyperlink to related SO question

@xeoncross
Copy link

@hakre, nice work. But you could also just do this:

print_r(json_decode(json_encode($node)));

@hakre
Copy link
Author

hakre commented May 18, 2012

@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.

@hakre
Copy link
Author

hakre commented Aug 24, 2012

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