Dom and xpath php



对于以前做过这件事的人来说,这应该是一个简单的问题!

我有一个表格格式的旧web文档列表,其中有很多出发和到达时间的详细信息。到目前为止,我所做的是创建一个PHP脚本,解析XHTML文档,获取出发和到达的时间以及对应关系。

文档格式示例:

<table borderColor="#ffffff" cellSpacing="3" cellPadding="0" width="550" border="0" align="center">
                    <tr align="left">
                        <td colSpan="5">Relation
                        <span class="ttr-orange3">
                        <span id="ctl00_ctl19_g_1f57e500_cfb9_4f21_8d34_37ed46a2c243_ctl00_rptHoraire_ctl00_lblRelationGare">BERRECHID - BENGUERIR</span></span></td>
                    </tr>
                    <tr align="center">
                        <td width="90" bgColor="#e2e2e2" height="26">Départ</td>
                        <td width="90" bgColor="#e2e2e2">Arrivée</td>
                        <td width="115" bgColor="#f0e9d9">Correspondance</td>
                        <td width="115" bgColor="#f0e9d9">Service à bord</td>
                        <td width="70" bgColor="#f0e9d9">Gamme</td>
                    </tr>
                    <tr align="center" bgcolor="#F7F2E9" onmouseover="style.backgroundColor='#F3EBDD';"
                        onmouseout="style.backgroundColor='#F7F2E9';">
                        <td height="20" bgcolor="#F4F4F4" width="90">05h21mn</td>
                        <td bgcolor="#F4F4F4" width="90">06h58mn</td>
                        <td width="115">-</td>
                        <td width="115"><img src='/Style%20Library/Images/CustomImages/pictos/bol.gif' width="15" height="13"></td>
                        <td width="70"><img src='/Style%20Library/Images/CustomImages/pictos/TRAIN_RAPIDE.gif' width="15" height="13"></td>
                    </tr>
                    <tr align="center" bgcolor="#F7F2E9" onmouseover="style.backgroundColor='#F3EBDD';"
                        onmouseout="style.backgroundColor='#F7F2E9';">
                        <td height="20" bgcolor="#F4F4F4" width="90">07h21mn</td>
                        <td bgcolor="#F4F4F4" width="90">08h56mn</td>
                        <td width="115">-</td>
                        <td width="115"><img src='/Style%20Library/Images/CustomImages/pictos/bol.gif' width="15" height="13"></td>
                        <td width="70"><img src='/Style%20Library/Images/CustomImages/pictos/TRAIN_RAPIDE.gif' width="15" height="13"></td>
                    </tr>
</table>

我需要做的是将所有这些[depart,arrivee,correspondace]细节解析到一个数组中。到目前为止,我已经掌握了基本知识:

$document = new DOMDocument();
@$document->loadHtml( $content );
$xpath = new DOMXPath($document);
$nodes = $xpath->query('//table[@width="580"]/tr');
$data = array();
foreach ($nodes as $node) {
   //Any help would be great!
}

我认为Xpath表达式中有一个拼写错误。HTML中表格的宽度为550。并且您不需要前两个tr元素,因此可以跳过它们。

$nodes = $xpath->evaluate('//table[@width="550"]/tr[position() > 2]');

您可以提供$node作为其他xpath表达式的上下文。DOMXpath::query()和DOMXpath::evaluate()支持这一点。但只有DOMXpath::evaluate()可以直接返回标量值。

$xpath->evaluate('string(td[1])', $node);

Xpath函数string()将第一个节点的文本内容强制转换为字符串。使用DOMXpath:query(),这将是:

$xpath->query('td[1]', $node)->item(0)->nodeValue;

示例:

$document = new DOMDocument();
@$document->loadHtml( $content );
$xpath = new DOMXPath($document);
$nodes = $xpath->evaluate('//table[@width="550"]/tr[position() > 2]');
$data = array();
foreach ($nodes as $node) {
  $data[] = array(
    'departure' => $xpath->evaluate('string(td[1])', $node),
    'arrival' => $xpath->evaluate('string(td[2])', $node),
    'info' => $xpath->evaluate('string(td[3])', $node)
  );
}
var_dump($data);

XPath表达式肯定与您提供的HTML代码不对应。我想你只想要真正的时间表,然后只想要前三列。假设HTML结构与上面的结构相似,那么第一步就是更改XPath,使其只匹配那些具有bgcolor属性的tr块。

$nodes = $xpath->query('//table[@width="550"]/tr[@bgcolor]');

接下来,您需要运行tr.中包含的td元素

foreach ($nodes as $node)
{
    foreach($node->childNodes as $childNode)
    {
        // --- process the td elements ---
    }
}

您可以运行所有td元素,然后跳过那些只包含空格的元素(这就是我在上面使用嵌套foreach概述的内容)。

在这种情况下,最好直接选择前3个td项,并将其nodeValue添加到数组中。

foreach ($nodes as $trNode)
{
    $tdNodes = $trNode->childNodes;
    $trData = array();
    for ($i = 0; $i < $tdNodes->length; $i++) 
    {
        $trData[] = $tdNodes->item($i)->nodeValue;
    }
    $data[] = $trData;
}

最后,您得到了一个2级$data数组,每个表行包含一个数组。然后,行阵列包含出发列车、到达列车和连接列车。

最新更新