2011-01-28 102 views
0

在下面的foreach循环,什么是正确的语法,以回报的关键字只有第一个实例,其包装以粗体标签,然后退出循环和功能?DOM文档的foreach更换

例如,关键字是“蓝色小工具”。所以我想在字符串(在$内容)的首次亮相,从蓝色小工具变为

<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; 
} 
+0

刚古玩,为什么不使用preg_replace? – Dmitri 2011-01-28 18:59:28

回答

0

你可以使用休息时间打破循环;

或者不能使用的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 
} 

不知道这是否会工作,但类似的东西...

2

正如德米特里提到的,仅仅只有第一个文本节点上运行。下面的示例采用解析包含关键字的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); 
} 

参考: