DOMDocument foreach замена - PullRequest
       10

DOMDocument foreach замена

0 голосов
/ 28 января 2011

В приведенном ниже цикле 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 ]

2 голосов
/ 29 января 2011

Как отметил Дмитрий, просто работайте только с первым текстовым узлом.В приведенном ниже примере используется подход к анализу узла 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);
}

Ссылка:

0 голосов
/ 28 января 2011

Вы можете просто выйти из цикла, используя 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
}

Не уверен, что это сработает, но что-то в этом роде ...

...