DOMDocument foreach替换

时间:2011-01-28 18:40:44

标签: php domdocument

在下面的foreach循环中,为了仅返回关键字的第一个实例,将其包装为粗体标记,然后退出循环和函数,正确的语法是什么?

例如,关键字是“蓝色小部件”。所以我希望字符串的第一次出现(在$ content中)从蓝色小部件更改为

<b>blue widgets</b>

这是我用来解析内容的例程......

function sx_decorate_keyword($content){
    $keyword = "blue widgets";
    $d = new DOMDocument();
    $d->loadHTML($content);
    $x = new DOMXpath($d);
    foreach($x->query("//text()[
       contains(.,$keyword')
       and not(ancestor::h1) 
       and not(ancestor::h2) 
       and not(ancestor::h3) 
       and not(ancestor::h4) 
       and not(ancestor::h5) 
       and not(ancestor::h6)]") as $node){
        //need to wrap bold tags around the first instance of the keyword, then exit the routine
    }  
return $content;
}

2 个答案:

答案 0 :(得分:2)

正如Dmitri所说,只是在第一个文本节点上工作。下面的示例采用剖析包含您的关键字的DOMText节点并将第一个匹配包装在<b>元素中的方法。

$nodes = $x->query("... your xpath ...");
if ($nodes && $nodes->length) {
    $node = $nodes->item(0);
    // Split just before the keyword
    $keynode = $node->splitText(strpos($node->textContent, $keyword));
    // Split after the keyword
    $node->nextSibling->splitText(strlen($keyword));
    // Replace keyword with <b>keyword</b>
    $replacement = $d->createElement('b', $keynode->textContent);
    $keynode->parentNode->replaceChild($replacement, $keynode);
}

参考:

答案 1 :(得分:0)

您可以使用 break;

突破循环

或者你不能使用foreach而只是只使用第一个元素。

    $Matches = $x->query("//text()[
           contains(.,$keyword')
           and not(ancestor::h1) 
           and not(ancestor::h2) 
           and not(ancestor::h3) 
           and not(ancestor::h4) 
           and not(ancestor::h5) 
           and not(ancestor::h6)]");

if($Matches && $Matches->length > 0){
  $myText = $Matches->item(0);
  // now do you thing with $myText like create <b> element, append $myText as child,
  // replaceNode $myText with new <b> node
}

不确定这是否有效,但是那样......