如何获取PHP中所有html元素的列表?

时间:2016-11-07 14:23:59

标签: php html dom

根据DOMDocument::getElementsByTagName的文档,我可以使用.col-xl-12.hscentertext { width: 100%; border-bottom: 1px solid #fff; } .img-fluid.center-block.text-xl-center { margin-bottom: -1px; } 参数调用该函数,并从一些HTML代码中获取所有HTML元素的列表。

但是,使用以下代码:

"*"

我得到一个只有一个元素的列表,上面代码的执行结果是:

<?php
  $dom = new DOMDocument();
  $dom->loadHTML("<html><body><div>hello</div><div>bye</div></body></html>");
  $nodes = $dom->getElementsByTagName("*");

  foreach ($nodes as $node) {
    $new_text= new DOMText($node->textContent."MODIFIED");

    $node->removeChild($node->firstChild);
    $node->appendChild($new_text);
  }
  $content = $dom->saveHTML();
  echo $content;
?>

虽然我期待这样的事情:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>hellobyeMODIFIED</html>

<html><body><div>helloMODIFIED</div><div>byeMODIFIED</div></body></html> 方法不应该返回HTML代码中可用的HTML元素列表吗?

注意:我需要显式创建DOMText实例,因为我需要在PHP 5.4中使用它。只能从PHP 5.6中编写DOMDocument::getElementsByTagName

3 个答案:

答案 0 :(得分:2)

如果第一个参数是DOMDocument::getElementsByTagName'*'方法实际上会返回所有标记。但是,您的代码在第一次迭代时用文本节点替换<body>标记(包括所有子节点)。

迭代节点,仅修改nodeType属性等于XML_TEXT_NODE的节点:

$nodes = $dom->getElementsByTagName('*');

foreach ($nodes as $node) {
  for ($child = $node->firstChild; $child; $child = $child->nextSibling) {
    if (! ($child->nodeType === XML_TEXT_NODE && trim($child->textContent))) {
      continue;
    }

    // The textContent is writable since PHP 5.6.1
    if (PHP_VERSION_ID >= 50601) {
      $child->textContent .= 'MODIFIED';
      continue;
    }

    // For older versions, create DOMText explicitly
    $text = new DOMText($child->textContent . 'MODIFIED');
    try {
      if ($child->parentNode->replaceChild($text, $child))
        $child = $text;
    } catch (Exception $e) {
      trigger_error("Failed to modify text '$child->textContent': "
        . $e->getMessage(), E_USER_WARNING);
    }
  }
}

echo $dom->saveHTML();

注意,对于PHP 5.6.1及更高版本,您不需要显式创建DOMText实例,因为DOMNode::textContent属性可以读写。因此,您可以通过为此属性指定字符串值来简单地修改文本。仅确保节点没有XML_TEXT_NODE以外的子节点。

上面的代码检查trim($child->textContent)是否为空,因为文档可能包含额外的空格字符(包括换行符),例如:

<div><!-- newline/spaces -->
  <span>text</span><!-- newline/spaces -->
</div><!-- newline/spaces -->

答案 1 :(得分:0)

试试这个: -

foreach($dom->getElementsByTagName('*') as $element ){

}

答案 2 :(得分:0)

此函数'DOMDocument :: getElementsByTagName'返回包含所有元素的类DOMNodeList的新实例。

它运作良好:

<?php
$dom = new DOMDocument();
  $dom->loadHTML("<html><body><div>hello</div><div>bye</div></body></html>");
  $nodes = $dom->getElementsByTagName("*");

  foreach ($nodes as $node) {
      echo $node->tagName."<br />";
  }
?>

输出文档的所有标记。

可能你需要像:

<?php


    $dom = new DOMDocument();
      $dom->loadHTML("<html><body><div>hello</div><div>bye</div></body></html>");
      $nodes = $dom->getElementsByTagName("*");

      foreach ($nodes as $node) {
          if ($node->tagName=='div'){
            $node->nodeValue .= "new content";
          }
      }

      $content = $dom->saveHTML();
      echo htmlspecialchars($content);

?>