跳到主要內容

PHP學習-LoadXML與網頁格式錯亂

· 閱讀需 3 分鍾

用php寫後端動態生成網頁內容的時候,用到了DOMDocument類的操作。為了減少創建元素和文本節點的代碼(與效率無關),使用了loadXML()方法載入靜態的HTML文本(通過heredoc)。

$xml = new DOMDocument(); $xml->loadXML(<<<_HTML <div class="-article"> <div class="-article-title" onselectstart="return false;"></div> <hr/> <div class="-article-body"></div> <hr/> <div class="-article-extra"></div> <div class="-aborted"></div> <div class="-article-picture"></div> </div> _HTML ); ...... echo xml->saveXML();

沒錯,就是用loadXML()載入HTML,這樣做是因為saveHTML()的時候會輸出完整的HTML文檔(包含html和body元素)而不是我想要的文章部分,而saveXML()則只需要去除首行的文檔聲明即可。

這裡不談這樣的做法好與不好,只說說我遇到的問題。

遇到的問題是,網頁版面亂了。出現了塊級元素的堆疊,就是生成的元素後面的同級元素變成了它的子元素。感覺是標籤沒有閉合導致的,用瀏覽器看了生成的網頁代碼,終於找到了問題所在。

耗子屎在這一行:

<div class="-aborted"></div>

由於一些原因,生成元素中這塊被廢棄了,後面的代碼又很多地方使用了getElementsByTagName方法獲取指定元素,需要靠子元素的位置定位,所以不好直接刪除(可見裝載靜態的html文檔結構並不是個好點子),於是把這個<div>的類名設置為-aborted,然後統一處理。因為是廢棄元素,所以自然也不會為它生成內容了,最後saveXML輸出的文本中,將這個空元素<div class="-aborted"></div>轉化成了<div class="-aborted"/>。在html5中自閉合標籤是有嚴格控制的,只有特定的標籤才允許,因此<div/>並沒有被瀏覽器認為是一個閉合的標籤,然後和後面的div塊混亂了,才導致的這個問題。

解決辦法是,給heredoc中的廢棄元素的內容加個空格,xml封裝器就不會將它當作空元素了。不過最好還是全都動態生成元素,少生么蛾子。或者使用其他更好的辦法。