0

我有一个看起来像这样的 xpath:

$path = '//*[@id="page-content"]/table/tbody/tr[3]/td['.$i.']/div/a';

$i1 到X的位置。我通常会使用:

for($i=1; $i<X;$i++){
  $path = '//*[@id="page-content"]/table/tbody/tr[3]/td['.$i.']/div/a';
  $nodelist = $xpath->query($path);
  $result = $nodelist->item(0)->nodeValue;
};

但是,在这种情况下,我不知道X是多少。有没有办法在不知道 X 的情况下循环遍历它?

4

4 回答 4

5

为什么不只是堆叠它们?类似的东西(脆弱的代码,添加你的检查):

// first xpath for the outer node-list
$tds = $xpath->query('//*[@id="page-content"]/table/tbody/tr[3]/td');
foreach ($tds as $td)
{
    // fetch the included values with a relative xpath to the current node
    $nodelist = $xpath->query('./div/a', $td);
    ...
}

实际上,您甚至不需要那个内部节点列表,因为您最终想查询节点值。然而,我把它留在这里是为了展示你可以通过使用相对于具体节点的 xpath 直接做些什么。


因此,如果您需要ID 为"page-content"的任何节点内任何表的第三个内的任何内的第一个 <a>元素,您可以直接编写它,这是一个查询: <div> <tr>

//*[@id="page-content"]/table/tbody/tr[3]/td/div/a[1]

谓词(即括号)仅适用于路径中前缀为它的节点,因此[1]is only fora在末尾,因为is only [3]for the tr.

代码示例:

$as = $xpath->query('//*[@id="page-content"]/table/tbody/tr[3]/td/div/a[1]');
foreach ($as as $a) 
{
    echo $a->nodeValue, "\n";
}

因此,这将为您提供单个节点列表的结果,您无需运行第二个 xpath 查询。

于 2012-11-09T15:25:49.010 回答
2

如果我理解您的问题,您是在问如何循环直到<td>XPath 下的最大元素数?

您可以使用以下方法检索节点数:

count(//*[@id="page-content"]/table/tbody/tr[3]/td)并将其存储为临时变量,然后在下一条语句中使用它,如下所示:

for($i=1; $i<numberOfTdElements;$i++){
  $path = '//*[@id="page-content"]/table/tbody/tr[3]/td['.$i.']/div/a';
  $nodelist = $xpath->query($path);
  $result = $nodelist->item(0)->nodeValue;
};

针对hakre的建议:

$tbody = $doc->getElementsByTagName('tbody')->item(0);

// our query is relative to the tbody node
$query = 'count(tr[3]/td)';

$tdcount = $xpath->evaluate($query, $tbody);
echo "There are $tdcount elements under tr[3]\n";

然后将它们全部结合起来:

for($i=1; $i<$tdcount;$i++){
      $path = '//*[@id="page-content"]/table/tbody/tr[3]/td['.$i.']/div/a';
      $nodelist = $xpath->query($path);
      $result = $nodelist->item(0)->nodeValue;
    };
于 2012-11-09T15:27:01.197 回答
0

I think what you are trying to do is fetch every a element that is a child of a div, which in its turn is a child of any td element that, in its turn, is a child of every third tr element, etc. If that is correct, you can simply fetch these with this query:

<?php 

$doc = new DOMDocument();
$doc->loadXML( $xml );
$xpath = new DOMXPath( $doc );
$nodes = $xpath->query( '//*[@id="page-content"]/table/tbody/tr[3]/td/div/a' );
foreach( $nodes as $node )
{
    echo $node->nodeValue . '<br>';
}

Where $xml is a document, similar to this:

<?php

$xml = <<<XML
<?xml version="1.0" encoding="utf-8" ?>
<result>
    <div id="page-content">
        <table>
            <tbody>
                <tr>
                    <td>
                        <div><a>This one shouldn't be fetched</a></div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div><a>This one shouldn't be fetched</a></div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div><a>This one shouldn't be fetched</a></div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</result>
XML;

In other words, no need to loop trough all these td elements. You can fetch them all in one go, resulting in a DOMNodeList with all required nodes.

于 2012-11-09T15:33:18.003 回答
0
$doc = new DOMDocument();

$doc->loadXML( $xml );

$xpath = new DOMXPath( $doc );

$nodes = $xpath->query( '/result/div[@id="page-content"]/table/tbody/tr[3]/td/div/a');

foreach( $nodes as $node )
{
    echo $node->nodeValue . '<br>';
}
于 2013-11-19T10:46:13.537 回答