我正试图以这种模式获取HTML ...
<p>a</p>
<p>b</p>
<p>c</p>
...
<h3>title</h3>
<p>e</p>
<p>e</p>
<p>f</p>
...
<h3>title2</h3>
...
......然后把它变成......
<ul>
<li>
<blockquote>
<p>a</p>
<p>b</p>
<p>c</p>
<cite>title</cite>
</blockquote>
</li>
<li>
<blockquote>
<p>d</p>
<p>e</p>
<p>f</p>
<cite>title2</cite>
</blockquote>
</li>
</ul>
我的PHP代码是......
$dom = new DOMDocument('1.0', 'utf-8');
$dom->preserveWhiteSpace = FALSE;
$dom->loadHTML($content);
$ul = $dom->createElement('ul');
$body = $dom->getElementsByTagName('body')->item(0);
$blockquote = FALSE;
foreach($body->childNodes as $element) {
if ($element->nodeType != XML_ELEMENT_NODE) {
continue;
}
if ( ! $blockquote) {
$blockquote = $dom->createElement('blockquote');
$li = $dom->createElement('li');
}
switch ($element->nodeName) {
case 'p':
$blockquote->appendChild($element);
break;
case 'h3':
$li->appendChild($blockquote);
$ul->appendChild($li);
$blockquote = $li = FALSE;
break;
}
}
$body->appendChild($ul);
echo $dom->saveHTML();
虽然功能尚未完成,但我注意到当我添加$blockquote->appendChild($element)
时循环停止。
如果删除所有appendChild
内容,则循环正常。
我的猜测是,通过在迭代中移动当前元素,它会打破循环。
我怎样才能让它发挥作用?
答案 0 :(得分:1)
如果在插入当前文档时出现窒息,您是否考虑过创建新文档?您可以使用DOMDocument上的importNode方法将旧文档中的正确位复制到您将在新文档中创建的正确结构中。
您可以使用document fragment使用类似的技巧,只使用序列化的XML而不是使用节点对象。这可能适用于段落标记,至少。
答案 1 :(得分:1)
你的猜测是正确的。因为childNodes反映了当前的DOM,所以以你正在进行的方式移动元素会混淆循环。
我过去成功使用过的一种技术(尽管我从未尝试过使用php)是以相反的顺序遍历childNodes。因为您将节点附加到childNodes列表的末尾,这意味着您始终使用自循环开始以来尚未移动的元素。
显然,您需要稍微更改ul / li / blockquote构造逻辑以允许进行逆序处理。