2014-01-27 58 views
0

我需要刪除HTML文檔中的一些標籤(例如<div></div>)並保留內部標籤和文本。 我設法用Simple HTML Dom Parser做到這一點。但由於巨大的內存需求,它無法處理大文件。 我更喜歡使用像DOMDocument這樣的原生PHP工具,因爲我讀到它在處理HTML文檔時更加優化和更快。 但我在第一階段掙扎 - 如何刪除一些標籤,同時保留內部文本和標籤。php dom文檔刪除一些html標籤但保留內部標籤和文本

HTML源代碼樣本是:

<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html> 

我試試這個代碼:

$htmltext='<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html>'; 
libxml_use_internal_errors(true); 
$doc = new DOMDocument(); 
$doc->loadHTML($htmltext); 
$oldnodes = $doc->getElementsByTagName('div'); 
foreach ($oldnodes as $node) { 
    $fragment = $doc->createDocumentFragment(); 
    while($node->childNodes->length > 0) { 
     $fragment->appendChild($node->childNodes->item(0)); 
    } 
    $node->parentNode->replaceChild($fragment, $node); 
} 
echo $doc->saveHTML(); 

它產生的輸出:

<html><body>00000aaaaa<div>bbbbbbccc<a>link</a>cccdddddd</div>eeeee<div>1111</div></body></html> 

我需要以下條件:

<html><body>00000aaaaabbbbbbccc<a>link</a>cccddddddeeeee1111</body></html> 

有人可以幫我解決這個問題嗎?

+0

如果文檔正文中只有一個標籤,則可以使用該零件的strip_tags使用其第二個參數在字符串中保留標籤。或者,您可以使用preg_replace刪除HTML字符串中的每個div標籤。 – SenseException

+0

有很多不同的標籤,我只想刪除不僅是div的特定標籤。 –

回答

0

我找到了一種方法讓它工作。 問題原因代碼不起作用的是nodelist中的節點在nodelist中的操作。所以「foreach」函數只能通過nodelist中的4個項目中的2個 - 其餘2個變形。

所以我不得不只處理列表的第一個元素,然後重建列表,直到列表中剩下一些項目。

的代碼是:

$htmltext='<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html>'; 
echo "<!-- 
".$htmltext." 
--> 
"; 
libxml_use_internal_errors(true); 
$doc = new DOMDocument(); 
$doc->loadHTML($htmltext); 
$oldnodes = $doc->getElementsByTagName('div'); 
while ($oldnodes->length>0){ 
    $node=$oldnodes->item(0); 
    $fragment = $doc->createDocumentFragment(); 
    while($node->childNodes->length > 0) { 
     $fragment->appendChild($node->childNodes->item(0)); 
    } 
    $node->parentNode->replaceChild($fragment, $node); 
    $oldnodes = $doc->getElementsByTagName('div'); 
} 
echo $doc->saveHTML(); 

我希望這將是人誰發現同樣的困難有幫助。

0

如果你的代碼只包含簡單的HTML標籤,沒有任何屬性,你可以保持它的簡單,如:

$value = '<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html>'; 
$pattern = '/<[\/]*(div|h1)>/'; 

$removedTags = preg_replace($pattern, '', $value); 

既然你在你的評論中寫道,有比你想只刪除div標籤多了,我加如果您還想要移除h1標籤,請在模式中使用h1標籤。

此代碼片段僅適用於簡單代碼,但適合您的HTML輸入和輸出示例。

+0

謝謝你選擇這個選項。標籤可以包含屬性。我喜歡使用Simple HTML DOM將HTML作爲DOM對象。因此,最好了解如何將標準工具(如DOM文檔)應用於此任務。 –

+0

如果這只是爲了獲得知識,而不是簡單的解決方案,那麼我不需要發佈也包含屬性的模式。使用DOMDocument刪除多個標記可以增加您的代碼量。讓我看看是否有時間用DOMDocument創建一個簡單的代碼片段。 – SenseException

+0

我會說我需要更多的通用解決方案,因爲我需要在第一批中處理約300k頁。當然,我無法在這裏發佈所有這些內容,但它們可以包含不同的屬性。我設法用PHP Simple HTML DOM解析器創建了部分工作解決方案。部分 - 導致某些頁面對於解析器處理(內存泄漏)太大。 –

0

試試這個.. 只需用下面的代碼替換for循環即可。

foreach ($oldnodes as $node) { 
    $children = $node->childNodes; 
    $string = ""; 
    foreach($children as $child) { 
     $childString = $doc->saveXML($child); 
     $string = $string."".$childString; 
    } 
    $fragment = $doc->createDocumentFragment(); 
    $fragment->appendXML($string); 
    $node->parentNode->insertBefore($fragment,$node); 
    $node->parentNode->removeChild($node); 
} 
+0

我改變了代碼,因爲沒有「appendHTML」,但是「appendXML」 而PHP不允許使用$ string。「」。$ child - 我必須使用$ string。「」。$ node-> ownerDocument-> saveHTML($子)。 改變的代碼產生相同的結果,我和我的代碼的問題 - 00000aaaaa

bbbbbbccclinkcccdddddd
EEEEE
1111

+0

@ user3240065檢查更新code.sorry我忘了補充$ childString = $ doc-> saveXML($子) ; – Vegeta

+0

感謝您提出這個選項。我試圖運行的代碼 - 它仍然產生輸出作爲我的代碼相同 - 00000aaaaa

bbbbbbccclinkcccdddddd
EEEEE
1111

1

您可以在PHP中使用strip_tags函數。

$thmltext = '<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html>'; 
strip_tags($htmltext, '<html>,<body>,<a>'); 

這去除所有標籤,除了HTML,身體,一個

和輸出是:

<html><body>00000aaaaabbbbbbccc<a>link</a>cccddddddeeeee1111</body></html> 

編輯: 如果是來自用戶的輸入,這對安全性更好使用白名單標記而不是黑名單的理由。

+0

感謝, 應該爲這個簡單的標記工作,但我有時候需要選擇其中的DIV基於刪除他們的屬性。例如。我可能想要刪除除id =「mw-panel」的div以外的所有div。這就是爲什麼我試圖熟悉DOMdocument。 –

相關問題