2013-04-21 10 views
9

Mam ciąg html, który zawiera dokładnie jeden element w nim. Przykład:Modyfikuj atrybut html za pomocą php

<a href="http://www.test.com" rel="nofollow external">test</a> 

w PHP muszę sprawdzić, czy rel zawiera zewnętrznego a jeśli tak, to zmodyfikować href i zapisać ciąg.

Szukałem węzłów DOM i obiektów. Ale wydają się być zbyt wiele dla tylko jednego elementu A, ponieważ muszę iterować, aby uzyskać węzły html i nie jestem pewien, jak przetestować, czy istnieje rel i zawiera zewnętrzny.

$html = new DOMDocument(); 
$html->loadHtml($txt); 
$a = $html->getElementsByTagName('a'); 
$attr = $a->item(0)->attributes(); 
... 

W tym momencie otrzymam listę NodeMapList, która wydaje się być narzutem. Czy jest jakiś prostszy sposób na to czy powinienem to zrobić z DOM?

+0

Gdy mamy do czynienia z DOM masz dwie opcje: 1) użycie natywnego DOM parser 2) Za pomocą wyrażenia regularnego (co jest na górze) – Yang

+0

dalej. Użyj 'DOMDocument()' do manipulowania – Yang

+0

Nikt nie powinien używać surowych metod DOM do manipulacji. Rozważ phpQuery lub QueryPath itp., Aby zmniejszyć żmudny schemat. – mario

Odpowiedz

9

Czy istnieje jakiś prostszy sposób na to, czy powinienem to zrobić z DOM?

Zrób to z DOM.

Oto przykład:

<?php 
$html = '<a href="http://example.com" rel="nofollow external">test</a>'; 
$dom = new DOMDocument; 
$dom->loadHTML($html); 
$xpath = new DOMXPath($dom); 
$nodes = $xpath->query("//a[contains(concat(' ', normalize-space(@rel), ' '), ' external ')]"); 
foreach($nodes as $node) { 
    $node->setAttribute('href', 'http://example.org'); 
} 
echo $dom->saveHTML(); 
0

Można użyć wyrażenia regularnego jak if it matches /\s+rel\s*=\s*".*external.*"/ następnie zrobić regexp zastąpić niczym /(<a.*href\s*=\s*")([^"]\)("[^>]*>)/\1[your new href here]\3/

Choć przy użyciu biblioteki, które można zrobić tego rodzaju rzeczy dla ciebie jest znacznie łatwiejsze (jak jQuery dla JavaScript)

2

Ciągle zamierzałem modyfikować przy pomocy DOM. Oto, co otrzymuję:

$html = new DOMDocument(); 
$html->loadHtml('<?xml encoding="utf-8" ?>' . $txt); 
$nodes = $html->getElementsByTagName('a'); 
foreach ($nodes as $node) { 
    foreach ($node->attributes as $att) { 
     if ($att->name == 'rel') { 
      if (strpos($att->value, 'external')) { 
       $node->setAttribute('href','modified_url_goes_here'); 
      } 
     } 
    } 
} 
$txt = $html->saveHTML(); 

Nie chciałem ładować żadnej innej biblioteki tylko dla tego jednego ciągu.

2

Najlepszym sposobem jest użycie parsera HTML/DOM, ale tu jest rozwiązanie regex:

$html = '<a href="http://www.test.com" rel="nofollow external">test</a><br> 
<p> Some text</p> 
<a href="http://test.com">test2</a><br> 
<a rel="external">test3</a> <-- This won\'t work since there is no href in it. 
'; 

$new = preg_replace_callback('/<a.+?rel\s*=\s*"([^"]*)"[^>]*>/i', function($m){ 
    if(strpos($m[1], 'external') !== false){ 
     $m[0] = preg_replace('/href\s*=\s*(("[^"]*")|(\'[^\']*\'))/i', 'href="http://example.com"', $m[0]); 
    } 
    return $m[0]; 
}, $html); 

echo $new; 

Online demo.

Powiązane problemy