【问题标题】:Loop through all elements of "body" tags using DOM使用 DOM 循环遍历“body”标签的所有元素
【发布时间】:2011-05-24 18:53:52
【问题描述】:
$html = file_get_contents("test.html");
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
$body = $xpath->query('//body');

我想遍历 HTML 文件的 body 标记的所有元素并打印出与这些元素关联的“样式”属性。我该怎么做?

【问题讨论】:

  • 是body元素的直接子元素还是body下面的整个元素树?
  • 我的意思是 body 下面的整个元素树 :)

标签: php html loops dom


【解决方案1】:

另一种选择是使用 XPath 仅查找源自 <body> 并具有 style 属性的元素,例如:

$dom = new DOMDocument;
$dom->loadHTMLFile('https://stackoverflow.com/questions/4431142/');

$xpath = new DOMXPath($dom);
$nodes = $xpath->query('/html/body//*[@style]');

foreach($nodes as $node) {
    printf(
        'Element %s - Styles: %s%s',
        $node->nodeName,
        $node->getAttribute('style'),
        PHP_EOL
    );
}

输出与Gordon's answer 中的相同,唯一重要的行是$nodes = … 一行。

【讨论】:

    【解决方案2】:

    您可以为此使用我的RecursiveDOMIterator

    代码(压缩)

    class RecursiveDOMIterator implements RecursiveIterator
    {
        protected $_position;
        protected $_nodeList;
        public function __construct(DOMNode $domNode)
        {
            $this->_position = 0;
            $this->_nodeList = $domNode->childNodes;
        }
        public function getChildren() { return new self($this->current()); }
        public function key()         { return $this->_position; }
        public function next()        { $this->_position++; }
        public function rewind()      { $this->_position = 0; }
        public function valid()
        {
            return $this->_position < $this->_nodeList->length;
        }
        public function hasChildren()
        {
            return $this->current()->hasChildNodes();
        }
        public function current()
        {
            return $this->_nodeList->item($this->_position);
        }
    }
    

    用法:

    $dom = new DOMDocument;
    $dom->loadHTMLFile('http://stackoverflow.com/questions/4431142/');
    
    $dit = new RecursiveIteratorIterator(
        new RecursiveDOMIterator($dom),
        RecursiveIteratorIterator::SELF_FIRST
    );
    
    foreach($dit as $node) {
        if($node->nodeType === XML_ELEMENT_NODE && $node->hasAttribute('style')) {
            printf(
                'Element %s - Styles: %s%s',
                $node->nodeName,
                $node->getAttribute('style'),
                PHP_EOL
            );
        }
    }
    

    输出:

    Element div - Styles: margin-top: 8px; height:24px;
    Element div - Styles: margin-top: 8px; height:24px; display:none;
    Element a - Styles: font-size: 200%; margin-left: 30px;
    Element div - Styles: display:none
    Element div - Styles: display:none
    Element span - Styles: color:#FE7A15;font-size:140%
    Element span - Styles: color:#FE7A15;font-size:140%
    Element span - Styles: color:#FE7A15;font-size:140%
    Element span - Styles: color:#E8272C;font-size:140%
    Element span - Styles: color:#00AFEF;font-size:140%
    Element span - Styles: color:#969696;font-size:140%
    Element span - Styles: color:#46937D;font-size:140%
    Element span - Styles: color:#C0D0DC;font-size:140%
    Element span - Styles: color:#000;font-size:140%
    Element span - Styles: color:#dd4814;font-size:140%
    Element span - Styles: color:#9ce4fe;font-size:140%
    Element span - Styles: color:#cf4d3f;font-size:140%
    Element span - Styles: color:#f4f28d;font-size:140%
    Element span - Styles: color:#0f3559;font-size:140%
    Element span - Styles: color:#f2f2f2;font-size:140%
    Element span - Styles: color:#037187;font-size:140%
    Element span - Styles: color:#f1e7cc;font-size:140%
    Element span - Styles: color:#e1cdae;font-size:140%
    Element span - Styles: color:#a2d9f6;font-size:140%
    

    【讨论】:

    • 非常感谢您的回答。它很棒而且很棒,完全按照我的预期工作:)
    【解决方案3】:

    我是这样递归地做的。我不确定它是否是最有效的方法。我在这个网页上试过这个方法,效果很好。

    $dom = new DOMDocument();
    $dom->loadHTML($html);
    
    $xpath = new DOMXPath($dom);
    $body = $xpath->query('//body')->item(0);
    
    recursePrintStyles($body);
    
    function recursePrintStyles($node)
    {
        if ($node->nodeType !== XML_ELEMENT_NODE)
        {
            return;
        }
    
        echo $node->tagName;
        echo "\t";
        echo $node->getAttribute('style');
        echo "\n";
    
        foreach ($node->childNodes as $childNode)
        {
            recursePrintStyles($childNode);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多