需要有关PHP DOM XPath解析表的帮助

时间:2009-02-26 13:17:45

标签: php parsing xpath

我最近刚刚阅读了PHP中的DOM模块,现在我正在尝试使用它来解析HTML文档。该页面说这是比使用preg更好的解决方案,但我很难搞清楚如何使用它。

该页面包含一个表格,其中包含日期的事件日期和事件数量。

首先,我需要从带有valign =“bottom”的tr中获取文本(日期),然后我需要获取所有tr的所有列值,其中valign =“top”低于该tr。我需要tr下面每个tr的所有列值,日期一直到下一个tr,valign =“bottom”(下一个日期)。列数据的tr数是未知的,可以是零或很多。

这就是页面上的HTML:

<table>
    <tr valign="bottom">
        <td colspan="4">2009-02-26</td>
    </tr>
    <tr valign="top">
        <td>21:00</td>
        <td>Column data</td>
        <td>Column data</td>
        <td>Column data</td>
    </tr>
    <tr valign="top">
        <td>23:00</td>
        <td>Column data</td>
        <td>Column data</td>
        <td>Column data</td>
    </tr>
    <tr valign="bottom">
        <td colspan="4">2009-02-27</td>
    </tr>
    <tr valign="top">
        <td>06:00</td>
        <td>Column data</td>
        <td>Column data</td>
        <td>Column data</td>
    </tr>
    <tr valign="top">
        <td>10:00</td>
        <td>Column data</td>
        <td>Column data</td>
        <td>Column data</td>
    </tr>
    <tr valign="top">
        <td>13:00</td>
        <td>Column data</td>
        <td>Column data</td>
        <td>Column data</td>
    </tr>
</table>

到目前为止,我已经能够获得前两个日期(我只对前两个日期感兴趣),但我不知道如何离开这里。

我用来获取日期时间的xpath查询是

$result = $xpath->query('//tr[@valign="bottom"][position()<3]);

现在我需要一种方法将当天的所有事件连接到日期,即。选择所有tds和所有列值,直到下一个日期tr。

3 个答案:

答案 0 :(得分:3)

$oldSetting = libxml_use_internal_errors( true ); 
libxml_clear_errors(); 

$html = new DOMDocument(); 
$html->loadHtmlFile('http://url/table.html'); 

$xpath = new DOMXPath( $html ); 
$elements = $xpath->query( "//table/tr" ); 

foreach ( $elements as $item ) {
  $newDom = new DOMDocument;
  $newDom->appendChild($newDom->importNode($item,true));

  $xpath = new DOMXPath( $newDom ); 

  foreach ($item->attributes as $attribute) { 

    for ($node = $item->firstChild; $node !== NULL; 
         $node = $node->nextSibling) {
      if (($attribute->nodeName =='valign') && ($attribute->nodeValue=='top'))
      {
        print($node->nodeValue); 
      }
      else
      {
        print("<br>".$node->nodeValue);
      }
    }
    print("<br>");
  } 
}

libxml_clear_errors(); 
libxml_use_internal_errors( $oldSetting ); 

答案 1 :(得分:0)

使用following-sibling()

答案 2 :(得分:0)

此XPath表达式

/table/tr/td[@colspan=4]

/table/tr[valign='bottom']/td

导致节点设置日期单元格。

如何在标记之间获取单元格?

/table/tr/td[not(@colspan=4)][preceding::td[@colspan=4][1]='2009-02-26']