2011-01-28 59 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); 
} 

參考: