從 PHP 5.4 和 Libxml 2.6 開始,目前有更簡單的方法
當您將 HTML 載入如下
$html->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
在輸出中,將沒有 doctype、html 或 body 標籤
(PHP 5, PHP 7, PHP 8)
DOMDocument::saveHTML — 使用 HTML 格式將內部文件轉儲到字串中
從 DOM 表示法建立 HTML 文件。 此函式通常在從頭開始建立新的 dom 文件後呼叫,如下例所示。
node
輸出文件子集的選用參數。
回傳 HTML,如果發生錯誤則回傳 false
。
範例 1:將 HTML 樹儲存到字串中
<?php
$doc = new DOMDocument('1.0');
$root = $doc->createElement('html');
$root = $doc->appendChild($root);
$head = $doc->createElement('head');
$head = $root->appendChild($head);
$title = $doc->createElement('title');
$title = $head->appendChild($title);
$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);
echo $doc->saveHTML();
?>
從 PHP 5.4 和 Libxml 2.6 開始,目前有更簡單的方法
當您將 HTML 載入如下
$html->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
在輸出中,將沒有 doctype、html 或 body 標籤
當儲存使用 LIBXML_HTML_NOIMPLIED 選項起始的 HTML 片段時,它最終會「損壞」,因為 libxml 需要根元素。 libxml 會嘗試修復該片段,方法是根據它在該片段中遇到的第一個開啟標籤,在字串結尾新增結束標籤。
例如
<h1>Foo</h1><p>bar</p>
最終會變成
<h1>Foo<p>bar</p></h1>
最簡單的解決方法是自行新增根標籤,然後稍後將其剝離
$html->loadHTML('<html>' . $content .'</html>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$content = str_replace(array('<html>','</html>') , '' , $html->saveHTML());
如果您從字串載入 HTML,請確保已設定字元集。
<?php
...
$html_src = '<html><head><meta content="text/html; charset=utf-8" http-equiv="Content-Type"></head><body>';
$html_src .= '...';
...
?>
否則字元集將為 ISO-8859-1!
若要解決 script 標籤問題,只需在 script 節點中新增一個空白文字節點,DOMDocument 將會很好地呈現 <script src="your.js"></script>。
如果您想要更簡單的方法來解決 <script> 標籤問題,請嘗試
<?php
$script = $doc->createElement ('script');\
// 建立一個空白文字節點會強制 <script></script>
$script->appendChild ($doc->createTextNode (''));
$head->appendChild ($script);
?>
<?php
// 使用 DOM 來修正不整潔的 HTML。
// Tyson Clugg <tyson@clugg.net> 的範例
//
// vim: syntax=php expandtab tabstop=2
function tidyHTML($buffer)
{
// 將我們的文件載入 DOM 物件中
$dom = @DOMDocument::loadHTML($buffer);
// 我們想要美觀的輸出
$dom->formatOutput = true;
return($dom->saveHTML());
}
// 開始輸出緩衝,使用我們美觀的
// 回呼函式來格式化輸出。
ob_start("tidyHTML");
?>
<html>
<p>這就像是將蘋果與橘子相比。
</html>
<?php
// 這將會隱含地呼叫,但我們會
// 手動呼叫它來說明重點。
ob_end_flush();
?>
上述程式碼會移除不整潔的 HTML
<html>
<p>這就像是將蘋果與橘子相比。
</html>
並將其清理成如下格式
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>這就像在比較蘋果和橘子一樣。
</p></body></html>
為了避免 script 標籤輸出為 <script />,你可以使用 DOMDocumentFragment 類別。
<?php
$doc = new DOMDocument();
$doc -> loadXML($xmlstring);
$fragment = $doc->createDocumentFragment();
/* 使用原始 XML 字串將 script 元素附加到 fragment (將保留其原始形式),如果成功,則將其插入 DOM 樹中 */
if($fragment->appendXML("<script type='text/javascript' src='$source'></script>") {
$xpath = new DOMXpath($doc);
$resultlist = $xpath->query("//*[local-name() = 'html']/*[local-name() = 'head']"); /* 命名空間安全的方法,用於查找所有 html 元素的子元素 head,應該只返回 1 個匹配項 */
foreach($resultlist as $headnode) // 插入 script 標籤
$headnode->appendChild($fragment);
}
$doc->saveXML(); /* 我們的 script 標籤仍然會是 <script></script> */
?>
如果你使用 loadHTML() (來源是來自其他網站) 建立你的 DOMDocument 物件,並想將你的變更傳回瀏覽器,你應該確保 HTTP Content-Type 標頭與你的 meta content-type 標籤值相符,因為現代瀏覽器似乎會忽略 meta 標籤,而只信任 HTTP 標頭。例如,如果你正在讀取 ISO-8859-1 文件,而你的網頁伺服器宣稱是 UTF-8,你需要使用 header() 函式來修正它。
<?php
header('Content-Type: text/html; charset=iso-8859-1');
?>
XHTML
如果輸出是 XHTML,請使用 saveXML() 函式。
saveHTML 的輸出範例
<select name="pet" size="3" multiple>
<option selected>mouse</option>
<option>bird</option>
<option>cat</option>
</select>
使用 saveXML 的符合 XHTML 輸出
<select name="pet" size="3" multiple="multiple">
<option selected="selected">mouse</option>
<option>bird</option>
<option>cat</option>
</select>
<?php
function getDOMString($retNode) {
if (!$retNode) return null;
$retval = strtr($retNode-->ownerDocument->saveXML($retNode),
array(
'></area>' => ' />',
'></base>' => ' />',
'></basefont>' => ' />',
'></br>' => ' />',
'></col>' => ' />',
'></frame>' => ' />',
'></hr>' => ' />',
'></img>' => ' />',
'></input>' => ' />',
'></isindex>' => ' />',
'></link>' => ' />',
'></meta>' => ' />',
'></param>' => ' />',
'default:' => '',
// 有時,您還必須解碼實體...
'"' => '"',
'&' => '&',
''' => ''',
'<' => '<',
'>' => '>',
' ' => ' ',
'©' => '©',
'«' => '«',
'®' => '®',
'»' => '»',
'™' => '™'
));
return $retval;
}
?>
在這篇文章 http://softontherocks.blogspot.com/2014/11/descargar-el-contenido-de-una-url_11.html 中,我找到一種使用 DOMDocument、loadHTMLFile 和 saveHTML() 取得 URL 內容的簡單方法。
function getURLContent($url){
$doc = new DOMDocument;
$doc->preserveWhiteSpace = FALSE;
@$doc->loadHTMLFile($url);
return $doc->saveHTML();
}