2011-01-06 10 views
7

że mam następujący kod HTMLJak mogę użyć XPath i DOM do zastąpienia węzła/elementu w php?

$html = ' 
<div class="website"> 
    <div> 
     <div id="old_div"> 
      <p>some text</p> 
      <p>some text</p> 
      <p>some text</p> 
      <p>some text</p> 
      <div class="a class"> 
       <p>some text</p> 
       <p>some text</p> 
      </div> 
     </div> 
     <div id="another_div"></div> 
    </div> 
</div> 
'; 

I chcę zastąpić #old_div z następujących czynności:

$replacement = '<div id="new_div">this is new</div>'; 

Aby dać efekt końcowy:

$html = ' 
<div class="website"> 
     <div> 
      <div id="new_div">this is new</div> 
      <div id="another_div"></div> 
     </div> 
    </div> 
'; 

Czy istnieje prosty funkcja cut-and-paste do tego przy pomocy PHP?


ostateczny kod roboczy dzięki pomóc wszystkim Gordona:

<?php 

$html = <<< HTML 
<div class="website"> 
    <div> 
     <div id="old_div"> 
      <p>some text</p> 
      <p>some text</p> 
      <p>some text</p> 
      <p>some text</p> 
      <div class="a class"> 
       <p>some text</p> 
       <p>some text</p> 
      </div> 
     </div> 
     <div id="another_div"></div> 
    </div> 
</div> 
HTML; 

$dom = new DOMDocument; 
$dom->loadXml($html); // use loadHTML if it's invalid XHTML 

//create replacement 
$replacement = $dom->createDocumentFragment(); 
$replacement ->appendXML('<div id="new_div">this is new</div>'); 

//make replacement 
$xp = new DOMXPath($dom); 
$oldNode = $xp->query('//div[@id="old_div"]')->item(0); 
$oldNode->parentNode->replaceChild($replacement , $oldNode); 
//save html output 
$new_html = $dom->saveXml($dom->documentElement); 

echo $new_html; 

?> 
+1

możliwy duplikat [Korzystanie z DOMXPath do zastąpienia węzła przy zachowaniu jego pozycji ...] (http://stackoverflow.com/questions/640815/using-domxpath-to-replace-a-node-while- utrzymanie pozycji) – Gordon

+1

Możesz użyć ** XPath, aby wybrać ** węzeł docelowy na ** zastąpić metodą DOM **. Nadanie tytułu. –

Odpowiedz

11

Ponieważ odpowiedź w połączonej duplikatu nie jest tak wszechstronna, dam przykład:

$dom = new DOMDocument; 
$dom->loadXml($html); // use loadHTML if its invalid (X)HTML 

// create the new element 
$newNode = $dom->createElement('div', 'this is new'); 
$newNode->setAttribute('id', 'new_div'); 

// fetch and replace the old element 
$oldNode = $dom->getElementById('old_div'); 
$oldNode->parentNode->replaceChild($newNode, $oldNode); 

// print xml 
echo $dom->saveXml($dom->documentElement); 

Z technicznego punktu widzenia nie potrzebujesz do tego XPath. Jednak może się zdarzyć, że Twoja wersja biblioteki libxml nie będzie mogła wykonać getElementById dla niezatwierdzonych dokumentów (id attributes are special in XML). W takim przypadku należy wymienić wezwanie do getElementById z

$xp = new DOMXPath($dom); 
$oldNode = $xp->query('//div[@id="old_div"]')->item(0); 

Demo on codepad


Aby utworzyć $newNode z węzłów podrzędnych bez konieczności tworzyć i dołączać elementy, jeden po drugim, można zrobić

$newNode = $dom->createDocumentFragment(); 
$newNode->appendXML(' 
<div id="new_div"> 
    <p>some other text</p> 
    <p>some other text</p> 
    <p>some other text</p> 
    <p>some other text</p> 
</div> 
'); 
+0

niesamowite dzięki Gordon, spróbuj teraz! – Haroldo

+0

@gordon 'Złapalny błąd krytyczny: Argument 2 przekazany do DOMNode :: replaceChild() musi być instancją DOMNode, null podaną w C: \ wamp \ www \ gv2010 \ user_area \ replacement-test.php na linii 24'? – Haroldo

+0

@Haroldo zaktualizowany. przepraszam, nie zwracałem uwagi. – Gordon

-7

użyj jquery hide() najpierw, aby ukryć konkretny div, a następnie użyj dopisz, aby dołączyć nowy div

$('#div-id').remove(); 
$('$div-id').append(' <div id="new_div">this is new</div>'); 
+2

Pytanie dotyczy PHP (po stronie serwera), a nie javascript (strona klienta). –

+3

plus, nawet jeśli było to po stronie klienta, że ​​twoje rozwiązanie jest błędne, ponieważ jest ono dołączane zamiast zastępowania, więc nie zachowałoby miejsca na serwerze ... – Haroldo

Powiązane problemy