【问题标题】:Need help with PHP DOM XPath parsing table需要有关 PHP DOM XPath 解析表的帮助
【发布时间】:2009-02-26 13:17:44
【问题描述】:

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

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

首先,我需要从具有 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>

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

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

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

现在我需要一种方法将那天的所有事件与日期联系起来,即。选择直到下一个日期 tr 之前的所有 td 和所有列值。

【问题讨论】:

    标签: php parsing xpath


    【解决方案1】:
    $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 ); 
    

    【讨论】:

      【解决方案2】:

      使用following-sibling()

      【讨论】:

      • 谢谢,但是你如何告诉 xpath 只选择具有 [valign="bottom"] 的节点的兄弟姐妹?如果我在我选择的日期使用 following-sibling::tr[@valign="top"] 当我只想要直到下一个日期 tr 的那些时,它将返回所有以下 tr?
      • 选择所有跟随当前 tr[@valign="bottom"] 的兄弟节点,但不跟随下一个的兄弟节点的节点。例如第一个:following-sibling::tr[@valign="bottom"][1] 而不是(following-sibling::tr[@valign="bottom"][2])
      【解决方案3】:

      这个 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']
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-07
        • 1970-01-01
        • 2020-08-30
        • 1970-01-01
        • 2011-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多