2011-02-12 49 views
24

我剛剛開始閱讀有關DOM的文檔和示例,以便抓取和解析文檔。在DOM中的DOMDocument

,比如我有文件部分如下圖所示:

<div id="showContent"> 
    <table> 
    <tr> 
     <td> 
     Crap 
     </td> 
    </tr> 
<tr> 
      <td width="172" valign="top"><a href="link"><img height="91" border="0" width="172" class="" src="img"></a></td> 
      <td width="10">&nbsp;</td> 
      <td valign="top"><table cellspacing="0" cellpadding="0" border="0"> 
       <tbody><tr> 
       <td height="30"><a class="px11" href="link">title</a><a><br> 
        <span class="px10"></span> 
       </a></td> 
       </tr> 
       <tr> 
       <td><img height="1" width="580" src="crap"></td> 
       </tr> 
       <tr> 
       <td align="right"> 
        <a href="link"><img height="16" border="0" width="65" src="/buy"></a> 
       </td> 
       </tr> 
       <tr> 
       <td valign="top" class="px10"> 
        <p style="width: 500px;">description.</p> 
       </td> 
       </tr> 
      </tbody></table></td> 
     </tr> 
    <tr> 
     <td> 
Crap 
     </td> 
    </tr> 
    <tr> 
     <td> 
     Crap 
     </td> 
    </tr> 
    </table> 
    </div> 

我嘗試使用下面的代碼來獲取所有tr標籤和分析是否有垃圾或信息在其內部:

$dom = new DOMDocument(); 
@$dom->loadHTML($html); 

$xpath = new DOMXPath($dom); 


$tags = $xpath->query('.//div[@id="showContent"]'); 
foreach ($tags as $tag) { 
    $string=""; 
    $string=trim($tag->nodeValue); 
    if(strlen($string)>3) { 
     echo $string; 
     echo '<br>'; 
    } 
} 

但是我越來越剛剛剝離的字符串沒有標籤,例如:

Crap 

Crap 
Title 
Description 

但我想獲得:

<tr> 
    <td>Crap</td> 
</tr> 
<tr> 
    <a href="link">title</a> 
</tr> 

如何保持HTML節點(標籤)?

+2

請參閱[PHP的DOMDocument中的innerHTML](http://stackoverflow.com/questions/2087103/innerhtml-in-phps-domdocument)。 – netcoder 2011-02-12 18:45:17

+2

您的XPath與div匹配。要獲得顯示的HTML,您必須使用不同的XPath查詢/查詢,然後將結果傳遞給`echo $ dom-> save($ node)`。請澄清你想要得到什麼。 – Gordon 2011-02-12 18:53:49

+0

@netcoder innerHTML在這裏根本不需要。 – Gordon 2011-02-12 18:57:58

回答

63

如果你想使用DOM,你必須理解這個概念。 DOM文檔中的所有內容(包括DOMDocument)都是一個節點。

DOMDocument是節點的分層樹結構。它從一個根節點開始。該根節點可以有子節點,並且所有這些子節點都可以有自己的子節點。基本上,DOMDocument中的所有內容都是某種類型的節點類型,無論是元素,屬性還是文本內容。

  HTML        Legend: 
     / \        UPPERCASE = DOMElement 
     HEAD BODY       lowercase = DOMAttr 
    /  \       "Quoted" = DOMText 
    TITLE  DIV - class - "header" 
    |    \ 
"The Title"  H1 
        | 
      "Welcome to Nodeville" 

上圖顯示了一個DOMDocument與一些節點。有兩個孩子(HEAD和BODY)的根元素(HTML)。連接線稱爲軸。如果沿着軸向TITLE元素的方向,你會看到它有一個DOMText葉子。這很重要,因爲它說明了一個經常被忽視的東西:

<title>The Title</title> 

不是一個,而是兩個節點。帶有DOMText子元素的DOME元素。同樣,這也是

<div class="header"> 

實際上是三個節點:帶有DOMAttr的DOMElement持有DOMText。因爲所有這些都從DOMNode繼承了它們的屬性和方法,所以必須熟悉

實際上,這意味着您提取的DIV鏈接到文檔中的所有其他節點。任何時候你都可以一直到根部,或者一直到葉子。它在那裏。您只需查詢或遍歷文檔以獲取所需的信息。

無論你是通過迭代的DIV還是使用getElementByTagName()或XPath都由你決定。您只需要瞭解您不是使用原始HTML,而是使用代表整個HTML文檔的節點。

如果您需要從文檔中提取特定信息的幫助,則需要說明要從中提取哪些信息。例如,你可以問如何獲取從表中的所有環節,那麼我們就可以回答是這樣的:

$div = $dom->getElementById('showContent'); 
foreach ($div->getElementsByTagName('a') as $link) 
{ 
    echo $dom->saveXML($link); 
} 

但除非你是更具體的,我們只能猜測哪些節點可能是相關的。

如果您需要關於如何使用DOM工作更多的例子和代碼段通過我以前的答案瀏覽到相關的問題:

到現在爲止,應該有每一個片段基本到中等UseCase您可能會使用DOM。

4

要創建解析器,您可以使用htmlDOM

這是非常簡單易用的使用PHP編寫的DOM解析器。通過使用它,您可以輕鬆獲取div標籤的內容。

例如,查找所有div標籤,其屬性值id的值爲text

$ret = $html->find('div[id=text]');