我试图在php中调试一个庞大而复杂的DOMDocument对象。理想情况下,如果我可以让DOMDocument以类似数组的格式输出,那就好了。
DOM文档:
$ dom = new DOMDocument();
$ dom-> loadHTML(“<html> <body> <p> Hello World </ p> </ body> </ html>”);
后续代码var_dump($ DOM); //或者其他等价物
这输出 :
DOMDocument对象()
而我希望它输出:
DOM文档:
HTML
=>体
==>点
===> Hello World
发布于 2018-04-16 20:33:22
这个答案可能有点晚,但我喜欢你的问题!
PHP没有直接内置任何内容来解决您的问题,所以没有XML转储或其他东西。
但是,PHP的RecursiveTreeIterator
Docs非常接近您的输出:
\-<html>
\-<body>
\-<p>
\-Hello World
(如果你的X(HT)ML结构看起来更复杂,它会更好看。)
它用起来非常简单(就像大多数迭代器)一样foreach
:
$tree = new RecursiveTreeIterator($iterator);
foreach($tree as $key => $value)
{
echo $value . "\n";
}
所以让我们给它一个标签(元素)的RecursiveIterator
提供<tag>
,DOMNodes
以及text
如果它们是textnodes:
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);
}
}
}
实际上,除非你有抽象代码,否则这是行不通的,但为了使代码看起来如何使用(最有趣的部分),让我们来看看它:
$iterator = new DOMRecursiveDecoratorStringAsCurrent($iterator);
$tree = new RecursiveTreeIterator($iterator);
foreach($tree as $key => $value)
{
echo $value . "\n";
}
你只需预览整个代码的调用方式(如前所述,您可以将其放入函数中,以便在代码中轻松访问以进行调试xmltree_dump
)可能是调用的函数:
$dom = new DOMDocument();
$dom->loadHTML("<html><body><p>Hello World</p></body></html>");
$iterator = new DOMRecursiveIterator($dom->documentElement);
$iterator = new DOMRecursiveDecoratorStringAsCurrent($iterator);
$tree = new RecursiveTreeIterator($iterator);
foreach($tree as $key => $value)
{
echo $value . "\n";
}
那么除了已经涵盖的代码之外,我们还得到了什么?首先有一个DOMRecursiveIterator
- 就是这样。其余的代码是标准DOMDocument
代码。
那我们来写一下DOMRecursiveIterator
。这是RecursiveIterator
最终需要的RecursiveTreeIterator
。它的装饰使得树的转储实际上将标记名打印在括号和文本中。
可能现在分享它的代码是值得的:
class DOMRecursiveIterator extends DOMIterator implements RecursiveIterator
{
public function hasChildren()
{
return $this->current()->hasChildNodes();
}
public function getChildren()
{
$children = $this->current()->childNodes;
return new self($children);
}
}
只需继续使用父类即可DOMIterator
(implements RecursiveIterator
Docs只是为了让它工作):
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);
}
}
就定义而言,这就是所需要的,但是我称之为抽象的代码仍然缺失。它只是某种简单的代理代码,它将相同的方法委托给另一个对象。相关模式称为装饰者。然而,这只是代码,先是Iterator
然后是RecursiveIterator
朋友:
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());
}
}
HP没有这个内置的,但你可以自己写这个很简单,可重用。正如前面所写,将它封装到一个称为函数的函数中是一个好主意,xmltree_dump
因此可以轻松调用它来进行调试:
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";
}
}
用法:
$dom = new DOMDocument();
$dom->loadHTML("<html><body><p>Hello World</p></body></html>");
xmltree_dump($dom->documentElement);
发布于 2018-04-16 21:22:15
http://usphp.com/manual/en/function.dom-domdocument-savexml.php这样参考下吧:
$dom->formatOutput = true;
echo $dom->saveXML();
https://stackoverflow.com/questions/-100008125
复制相似问题