首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在PHP中调试DOMDocument对象?

如何在PHP中调试DOMDocument对象?
EN

Stack Overflow用户
提问于 2018-04-16 12:09:56
回答 2查看 0关注 0票数 0

我试图在php中调试一个庞大而复杂的DOMDocument对象。理想情况下,如果我可以让DOMDocument以类似数组的格式输出,那就好了。

DOM文档:

代码语言:javascript
复制
$ dom = new DOMDocument();
$ dom-> loadHTML(“<html> <body> <p> Hello World </ p> </ body> </ html>”);
后续代码var_dump($ DOM); //或者其他等价物

这输出 :

代码语言:javascript
复制
DOMDocument对象() 

而我希望它输出:

代码语言:javascript
复制
DOM文档:
HTML
=>体
==>点
===> Hello World
EN

回答 2

Stack Overflow用户

发布于 2018-04-16 20:33:22

这个答案可能有点晚,但我喜欢你的问题!

PHP没有直接内置任何内容来解决您的问题,所以没有XML转储或其他东西。

但是,PHP的RecursiveTreeIteratorDocs非常接近您的输出:

代码语言:javascript
复制
\-<html>
  \-<body>
    \-<p>
      \-Hello World

(如果你的X(HT)ML结构看起来更复杂,它会更好看。)

它用起来非常简单(就像大多数迭代器)一样foreach

代码语言:javascript
复制
$tree = new RecursiveTreeIterator($iterator);
foreach($tree as $key => $value)
{
    echo $value . "\n";
}

所以让我们给它一个标签(元素)的RecursiveIterator提供<tag>DOMNodes以及text如果它们是textnodes:

代码语言:javascript
复制
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);
        }
    }
}

实际上,除非你有抽象代码,否则这是行不通的,但为了使代码看起来如何使用(最有趣的部分),让我们来看看它:

代码语言:javascript
复制
$iterator = new DOMRecursiveDecoratorStringAsCurrent($iterator);
$tree = new RecursiveTreeIterator($iterator);
foreach($tree as $key => $value)
{
    echo $value . "\n";
}

你只需预览整个代码的调用方式(如前所述,您可以将其放入函数中,以便在代码中轻松访问以进行调试xmltree_dump)可能是调用的函数:

代码语言:javascript
复制
$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。它的装饰使得树的转储实际上将标记名打印在括号和文本中。

可能现在分享它的代码是值得的:

代码语言:javascript
复制
class DOMRecursiveIterator extends DOMIterator implements RecursiveIterator
{
    public function hasChildren()
    {
        return $this->current()->hasChildNodes();
    }
    public function getChildren()
    {
        $children = $this->current()->childNodes;
        return new self($children);
    }
}

只需继续使用父类即可DOMIteratorimplements RecursiveIteratorDocs只是为了让它工作):

代码语言:javascript
复制
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朋友:

代码语言:javascript
复制
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因此可以轻松调用它来进行调试:

代码语言:javascript
复制
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";
    }
}

用法:

代码语言:javascript
复制
$dom = new DOMDocument();
$dom->loadHTML("<html><body><p>Hello World</p></body></html>");
xmltree_dump($dom->documentElement);
票数 0
EN

Stack Overflow用户

发布于 2018-04-16 21:22:15

http://usphp.com/manual/en/function.dom-domdocument-savexml.php这样参考下吧:

代码语言:javascript
复制
$dom->formatOutput = true;
echo $dom->saveXML();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100008125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档