php中的DOMDocument

Sai*_*ios 25 php html-parsing domdocument xml-parsing

我刚刚开始阅读有关DOM的文档和示例,以便抓取和解析文档.

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

    <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>
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用以下代码来获取所有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>';
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我只是在没有标签的情况下剥离了字符串,例如:

Crap

Crap
Title
Description
Run Code Online (Sandbox Code Playgroud)

但我想得到:

<tr>
   <td>Crap</td>
</tr>
<tr>
   <a href="link">title</a>
</tr>
Run Code Online (Sandbox Code Playgroud)

如何保留html节点(标签)?

Gor*_*don 66

如果您想使用DOM,您必须了解这个概念.DOM文档中的所有内容(包括DOMDocument)都是Node.

DOMDocument是节点的分层树结构.它以根节点开始.该根节点可以具有子节点,并且所有这些子节点可以自己拥有子节点.基本上a DOMDocument中的所有东西都是某种节点类型,无论是元素,属性还是文本内容.

          HTML                               Legend: 
         /    \                              UPPERCASE = DOMElement
       HEAD  BODY                            lowercase = DOMAttr
      /          \                           "Quoted"  = DOMText
    TITLE        DIV - class - "header"
     |             \
"The Title"        H1
                    |
           "Welcome to Nodeville"
Run Code Online (Sandbox Code Playgroud)

上图显示了带有一些节点的DOMDocument.有一个带有两个子元素(HEAD和BODY)的根元素(HTML).连接线称为轴.如果沿着轴跟随TITLE元素,您将看到它有一个DOMText叶.这很重要,因为它说明了一个经常被忽视的事情:

<title>The Title</title>
Run Code Online (Sandbox Code Playgroud)

不是一个,而是两个节点.带有DOMText子项的DOMElement.同样,这个

<div class="header">
Run Code Online (Sandbox Code Playgroud)

实际上是三个节点:带有DOMAttr持有DOMText的DOMElement.因为所有这些都从DOMNode继承了它们的属性和方法,所以必须熟悉DOMNode类.

实际上,这意味着您获取的DIV链接到文档中的所有其他节点.您可以随时前往根元素或向下到叶子.一切都在那里.您只需查询或遍历文档以获取所需信息.

无论你做的是通过遍历childNodes中的DIV或使用getElementByTagName()XPath或由你.您只需要了解您不使用原始HTML,而是使用表示整个HTML文档的节点.

如果您需要有关从文档中提取特定信息的帮助,则需要说明要从中获取的信息.例如,您可以询问如何从表中获取所有链接,然后我们可以回答以下内容:

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

但除非你更具体,否则我们只能猜测哪些节点可能是相关的.

如果您需要更多关于如何使用DOM的示例和代码片段,请浏览我之前对相关问题的回答:

到目前为止,对于DOM可能存在的每个基本到中等的UseCase都应该有一个片段.

  • +1 ...我一直在寻找最长时间的Nodeville地图! (5认同)
  • 感谢Gordon,我需要这样的东西来了解dom是如何工作的,但我认为我不能用它来抓取我需要的信息,因为他们没有遵循任何标准而且没有类,id,或者没有那样,只是表:(信息是有用的,无论如何学习如何使用它= D. (2认同)