【问题标题】:How to wrap the elements by div according to the elements tree structure?如何根据元素树结构将元素通过div包裹起来?
【发布时间】:2015-08-17 11:42:30
【问题描述】:

我已经这样做了 2 天,但没有运气。我尝试使用Dom parser class 和循环方法,但它们都非常混乱,无法得到解决方案。

目标: 我需要用 div 包装 h 标签。父子关系就像 h1->h2->h3 等等。所以,我需要按照树形结构来包装div。

HTML

$html='<h1>some text<h1>
sometext
<h2>some text</h2>
sometext

<h1>some text<h1>
sometext
<h2>some text</h2>
sometext
<h3>some text</h3>
sometext';

预期输出

<div class="sect1">
<h1>some text<h1>
sometext
<div class="sect2">
<h2>some text</h2>
sometext
</div>
</div>

<div class="sect1">
<h1>some text<h1>
sometext
<div class="sect2">
<h2>some text</h2>
sometext
<div class="sect3">
<h3>some text</h3>
 sometext
</div>
</div>
</div>

尝试 1:

$dom = new DOMDocument();
$dom->loadHTML($html);
$elements = $dom->getElementsByTagName('*');

        for ($i = 0; $i < $elements->length; $i++) {            
        $element = $elements->item($i);
        if ($element->tagName == 'h1'){ 
           $wrap1 = $dom->createElement('div');
           $wrap1->setAttribute('class', 'sect1');

            $wrap1->appendChild($element);
            $dom->appendChild($wrap1);
        }
        if ($element->tagName == 'h2'){ 
           $wrap2 = $dom->createElement('div');
           $wrap2->setAttribute('class', 'sect2');

            $wrap2->appendChild($element);
            $wrap1->appendChild($wrap2);
            $dom->appendChild($wrap1);
        }
    }     

尝试 2:

$f=file("extractedadd.xhtml");
for($i=0;$i<count($f);$i++){
    if(strpos($f,'<h1 class="title"')!==false);
    $h1[].=$i;  
}
$h2count=0;
$h3count=0;
for($j=0;$j<count($h1);$j++){
  for($k=$h1[$j];$k<$h1[$j+1];$k++){
      if(strpos($f[$k],'<h2 class="title"')!==false){$h2=$h2count+1;}
      if(strpos($f[$k],'<h3 class="title"')!==false){$h3=$h3count+1;}

 }
 if($h2count!=0){
 for($z=1;$z<=$h2count;$z++){
     $to2.="</div>\n";
 }
 $r=str_replace('<h1 class="title"',$to2."</div>\n".'<h1 class="title"',$h1[$j]);
 $to2="";
}//something like this.

请帮忙!如何获得我预期的解决方案?

【问题讨论】:

  • 我们可以假设该行看起来完全如此 - 所有
  • 所有h 元素都在不同的行中
  • 那么解释起来就更简单了。我只是尝试

标签: php html dom


【解决方案1】:

我做了一点难度结构

$html='<h1>some text<h1>
sometext
<h2>some text</h2>
sometext

<h2>some text</h2>
one more sometext

<h1>some text<h1>
sometext
<h2>some text</h2>
sometext
<h3>some text</h3>
sometext';

$level = 0;
$array = split("\n", $html); // make array of lines
foreach($array as $line)  {
  if (preg_match('/\s*\<h(\d+)/i', $line, $matches)) {
     $l = $matches[1];  // take new level from tag h
     if ($level == $l) echo "</div>\n<div class=\"sect.$l.\">\n"; // the same level
     else {
        while ($level >= $l) {echo "</div>\n"; $level--; }
        while ($level < $l) {echo "<div class=\"sect".$l."\">\n"; $level++; }
     }
  }
  echo $line."\n";   
}
While ($level >= 1) {echo "</div>\n"; $level--; } // close not closed :)

Whatch there working

【讨论】:

  • 非常感谢!效果很好。但我有一个问题。有人说HTML 操作应该只用dom parser 来完成,如果我们使用regex 和其他一些东西它会崩溃。这是真的吗?
  • 问题是真正的 html 在扫描时可能很难准确理解您所处的位置。许多属性、嵌套级别和标签等。因此,我从任何网站获取的 html 代码将无法正常工作。它实际上只是文本扫描,而不是构建 dom 树。当您保存输入字符串的结构时,它会没问题
  • 感谢您的解释!
  • 我陷入了困境。我想将结果保存到文件中。上面的代码有点混乱。
  • 在开头$output = ""; 并通过$output .= 更改所有回声。最后使用字符串 $output。或者使用输出缓冲
猜你喜欢
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
  • 2012-06-02
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多