我有一个看起来像这样的xpath:
$path = '//*[@id="page-content"]/table/tbody/tr[3]/td['.$i.']/div/a';
其中$i
从1变为 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的情况下循环这个?
答案 0 :(得分:5)
为什么不叠加em?像(脆弱的代码,添加你的支票):
// 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直接做什么。
因此,如果您需要内的 {/ em> <a>
<div>
{/ 1>} <tr>
任何节点内任何表的“page-content”,您可以直接编写它,它是一个查询:
//*[@id="page-content"]/table/tbody/tr[3]/td/div/a[1]
谓词(即括号)仅适用于前缀为路径的节点,因此[1]
仅适用于a
,仅适用于[3]
对于tr
。
代码示例:
$as = $xpath->query('//*[@id="page-content"]/table/tbody/tr[3]/td/div/a[1]');
foreach ($as as $a)
{
echo $a->nodeValue, "\n";
}
因此,这会将结果作为单个节点列表提供给您,您不需要运行第二个xpath查询。
答案 1 :(得分:2)
如果我理解你的问题,你问的是如何循环直到XPath下的<td>
元素的最大数量?
您可以使用以下方法检索节点数:
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;
};
答案 2 :(得分:0)
我认为您要做的是获取a
的每个div
元素,该元素又是td
元素的子元素,轮流,是每个第三个 tr
元素的子元素等。如果这是正确的,您只需使用此查询获取这些元素:
<?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>';
}
$xml
是一个文档,类似于:
<?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;
换句话说,无需循环遍历所有这些td
元素。您可以一次性获取它们,从而生成包含所有必需节点的DOMNodeList
。
答案 3 :(得分: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>';
}