2009-04-20 113 views
27

我在PHP中使用DOM擴展來構建一些HTML文檔,並且我希望輸出格式良好(使用新行和縮進)以便它可讀,但是,從衆多測試中,我所做的:PHP「漂亮打印」HTML(不是整潔)

  1. 「formatOutput = true」 不會與saveHTML()方法,僅saveXML()在所有的工作
  2. 即使我用saveXML(),它仍然只適用於通過DOM創建的元素,所包含的loadHTML()不元件,即使採用「preserveWhiteSpace =假」

如果有人知道不同,我真的很想知道他們是如何運作的。

所以,我有一個DOM文檔,並且我使用saveHTML()來輸出HTML。因爲它來自DOM,我知道它是有效的,所以不需要以任何方式「整理」或驗證它。

我只是尋找一種方法來從我從DOM擴展接收到的輸出中獲得格式良好的輸出。

NB。正如你可能已經猜到的那樣,我不想使用Tidy擴展作爲a)它也做了很多事情,我也需要它(標記已經有效),b)它實際上對HTML內容進行了更改(例如HTML 5文檔類型和一些元素)。

追問:

OK,有了答案的幫助下我已經工作了,爲什麼DOM擴展是行不通的。雖然給出的例子有效,但它仍然沒有處理我的代碼。在this評論的幫助下,我發現如果您有任何文本節點,其中isWhitespaceInElementContent()爲true,則不會在該點之後應用任何格式。無論preserveWhiteSpace是否爲假,都會發生這種情況。解決方案是刪除所有這些節點(儘管我不確定這是否會對實際內容產生不利影響)。

回答

29

你是對的,似乎沒有HTML的縮進(others are also confused)。 XML工作,即使加載代碼。

<?php 
function tidyHTML($buffer) { 
    // load our document into a DOM object 
    $dom = new DOMDocument(); 
    // we want nice output 
    $dom->preserveWhiteSpace = false; 
    $dom->loadHTML($buffer); 
    $dom->formatOutput = true; 
    return($dom->saveHTML()); 
} 

// start output buffering, using our nice 
// callback function to format the output. 
ob_start("tidyHTML"); 

?> 
<html> 
    <head> 
    <title>foo bar</title><meta name="bar" value="foo"><body><h1>bar foo</h1><p>It's like comparing apples to oranges.</p></body></html> 
<?php 
// this will be called implicitly, but we'll 
// call it manually to illustrate the point. 
ob_end_flush(); 
?> 

結果:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html> 
<head> 
<title>foo bar</title> 
<meta name="bar" value="foo"> 
</head> 
<body> 
<h1>bar foo</h1> 
<p>It's like comparing apples to oranges.</p> 
</body> 
</html> 

與saveXML()一樣的...

<?xml version="1.0" standalone="yes"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html> 
    <head> 
    <title>foo bar</title> 
    <meta name="bar" value="foo"/> 
    </head> 
    <body> 
    <h1>bar foo</h1> 
    <p>It's like comparing apples to oranges.</p> 
    </body> 
</html> 

大概忘了把preserveWhiteSpace =假loadHTML過嗎?

免責聲明:我從tyson clugg/php manual comments盜走了大部分演示代碼。懶惰的我。


UPDATE:我現在還記得幾年前,我嘗試過同樣的事情,碰到了同樣的問題。我通過應用一個骯髒的解決方法(不是性能關鍵)來解決這個問題:我只是以某種方式在SimpleXML和DOM之間進行了轉換,直到問題消失。我想轉換擺脫了這些節點。也許用dom加載,用simplexml_import_dom導入,然後輸出字符串,再次用DOM解析這個,然後然後打印出來很漂亮。據我記得這工作(但它是真的慢)。

+0

謝謝。用你的例子和php.net上的評論,我已經解決了這個問題(參見上面的後續內容)。 – 2009-04-20 15:15:05

0

您可以使用代碼爲htmLawedhl_tidy功能。

// indent using one tab per indent, with all HTML being within an imaginary div 
$out = hl_tidy($in, 't', 'div')