2013-04-10 28 views
9

Yerleşik DOMDocument kullanarak bir HTML belgesindeki komut dosyalarını kaldırmak için @Alex's approach here kullandım. Sorun, Javascript içeriğiyle bir komut dosyası etiketim ve harici bir Javascript kaynak dosyasına bağlanan başka bir komut dosyası etiketim varsa, tüm komut dosyası etiketlerinin HTML'den kaldırılmamasıdır.DOMDocument betik etiketlerini HTML kaynağından kaldırma

$result = ' 
<!doctype html> 
<html> 
    <head> 
     <meta charset="utf-8"> 
     <title> 
      hey 
     </title> 
     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
     <script> 
      alert("hello"); 
     </script> 
    </head> 
    <body>hey</body> 
</html> 
'; 

$dom = new DOMDocument(); 
if($dom->loadHTML($result)) 
{ 
    $script_tags = $dom->getElementsByTagName('script'); 

    $length = $script_tags->length; 

    for ($i = 0; $i < $length; $i++) { 
     if(is_object($script_tags->item($i)->parentNode)) { 
      $script_tags->item($i)->parentNode->removeChild($script_tags->item($i)); 
     } 
    } 

    echo $dom->saveHTML(); 
} 

Yukarıdaki kod çıkışları: Eğer çıkış görebileceğiniz gibi

<html> 
    <head> 
     <meta charset="utf-8"> 
     <title>hey</title> 
     <script> 
     alert("hello"); 
     </script> 
    </head> 
    <body> 
     hey 
    </body> 
</html> 

, sadece dış komut dosyası etiketi çıkarıldı. Tüm komut dosyası etiketlerinin kaldırıldığından emin olmak için yapabileceğim bir şey var mı?

cevap

19

Hatanız gerçekten önemsiz. Bir DOMNode nesnesi (ve tüm torunları - DOMElement, DOMNodeList ve diğer birkaç kişi!), Ana öğesi değiştiğinde, özellikle de çocuk sayısı değiştiğinde, otomatik olarak güncellenir. Bu, PHP belgesinde birkaç satırda yazılır, ancak çoğunlukla halı altında süpürülür.

($k instanceof DOMNode)->length kullanarak döngü yaparsanız ve daha sonra düğümlerden öğeleri kaldırırsanız, length özelliğinin gerçekten değiştiğini fark edeceksiniz! Bunu ve diğer birkaç tuhaflığa karşı koymak için kendi kütüphanemi yazmam gerekiyordu.

çözüm: Aslında döngü değilim

if($dom->loadHTML($result)) 
{ 
    while (($r = $dom->getElementsByTagName("script")) && $r->length) { 
      $r->item(0)->parentNode->removeChild($r->item(0)); 
    } 
echo $dom->saveHTML(); 

- sadece bir defada ilk elemanını bir patlama. Sonuç: http://sebrenauld.co.uk/domremovescript.php

+0

Bu işe yaradı, teşekkürler! – RandomCoder

+6

Başka bir çözüm, sadece ters sırayla elemanların üstesinden gelmektir. – CBroe

4

Bir canlı düğüm listesinin sürprizlerle almak kaçınmak için - Eğer düğümlerini silmek olarak kısaldıkça - Eğer iterator_to_array kullanarak bir diziye kopyasıyla işe yarayabilir:

foreach(iterator_to_array($dom->getElementsByTagName($tag)) as $node) { 
    $node->parentNode->removeChild($node); 
}; 
+1

Fantastik, teşekkürler. – Jonathan

+0

+1 kabul edilen cevaptan çok daha basit - 1 nodu listelerinde “iterator_to_array()” ifadesi kullanılıyor, değişiklik yapmak için belgeyi değiştirirken temelde bir zorunluluktur. –