首页 > 解决方案 > PHP迭代html字符串的每个节点,包括被其他节点分割的文本节点

问题描述

我尝试使用 DOMDocument 和 DOMXPath 更改给定 HTML 代码的每个可读部分

$dom = new DOMDocument();
$dom->loadHTML('
    <h3> 
        TEST_1
        <b>b tag content</b>
        TEST_2
    </h3> 
    <p>p tag content </p>
');

$xpath = new DOMXPath($dom);

foreach ($xpath->evaluate('//*[count(*) = 0]') as $node) {
  $node->nodeValue = "Changed " . $node->nodeValue;
}

echo $dom->saveHTML();

它给了我

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
    <body>
        <h3> 
            TEST_1
            <b>Changed b tag content</b>
            TEST_2
        </h3> 
        <p>Changed p tag content</p>
    </body>
</html>

但是字符串“TEST_1”和“TEST_2”没有改变,因为 $xpath->evaluate('// [ count( ) = 0 ]') 只给了我没有子节点的节点。

  1. 如何获取具有“TEST_1”和“TEST_2”等节点的所有节点?
  2. 如何防止添加<html><body>标签结果?

标签: phpxpath

解决方案


不幸的是,我没有找到正确的 xpath 表达式。通过递归解决了这个问题。这有效:

function rewrite_all_nodes(&$node) {    
   if(count($node->childNodes) > 1){
      foreach($node->childNodes as $sub_node){
            change_all_nodes($sub_node);
      }
   } else {
      if(!empty(trim($node->nodeValue))){
         $node->nodeValue = "Changed";       
      }
   }
}

为了切断<body><html>标记我发现了这个https://stackoverflow.com/a/38079328/14495402

如果您知道 xpath 样式的解决方案,请分享))


推荐阅读