PHP with DOMXPath - 如何 select 并从此 html 树计数
PHP with DOMXPath - How to select and count from this html tree
我需要统计这些项目有多少是开放的,它们有四种类型:简单、中等、困难和不想要。所有这些类型都是 div 中的值。我需要从计数中排除 'Not-Wanted' 类型。请注意 'Open' 和 'Close' 值周围有不同数量的空格。这是 html 结构:
<table>
<tbody>
<tr>
<td>
<div>Difficult</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Closed </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Medium</div>
</td>
<td>Name</td>
<td>Open </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Medium</div>
</td>
<td>Name</td>
<td> Closed</td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td>Closed </td>
</tr>
<tr>
<td>
<div>Not-wanted</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Difficult</div>
</td>
<td>Name</td>
<td>Open</td>
</tr>
............
这是我解决问题的尝试之一。明明是错的,就是不知道怎么改正。
$doc = new DOMDocument();
$doc->loadHtmlFile('http://www.nameofsite.com');
$doc->preserveWhiteSpace = false;
$xpath = new DOMXPath($doc);
$elements = $xpath->query("/html/body/div[1]/div/section/div/section/article/div/div[1]/div/div/div[2]/div[1]/div[2]/div/section/div/div/table/tbody/tr");
$count = 0;
foreach ($elements as $element) {
if ($element->childNodes->nodeValue != 'Not-wanted') {
if ($element->childNodes->nodeValue === 'open') {
$count++;
}
}
}
echo $count;
我对 DOMXPath 有非常基本的了解,所以它对我来说太复杂了,因为我只能创建简单的查询。
有人可以帮忙吗?
提前致谢。
根据您示例中的数据,我认为您可以将 xpath 表达式调整为此以获得所有符合您条件的 <tr>
:
//table/tbody/tr[normalize-space(td[3]/text()) = 'Open' and
td[1]/div/text() != 'Not-wanted']
$elements
是 DOMNodeList 类型,然后您可以获取 length
属性 以获取列表中的节点数。
例如:
$source = <<<SOURCE
<table>
<tbody>
<tr>
<td>
<div>Difficult</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Closed </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Medium</div>
</td>
<td>Name</td>
<td>Open </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Medium</div>
</td>
<td>Name</td>
<td> Closed</td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td>Closed </td>
</tr>
<tr>
<td>
<div>Not-wanted</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Difficult</div>
</td>
<td>Name</td>
<td>Open</td>
</tr>
</tbody>
</table>
SOURCE;
$doc = new DOMDocument();
$doc->loadHTML($source);
$doc->preserveWhiteSpace = false;
$xpath = new DOMXPath($doc);
$elements = $xpath->query("//table/tbody/tr[normalize-space(td[3]/text()) = 'Open' and td[1]/div/text() != 'Not-wanted']");
echo $elements->length;
这将导致:
5
我需要统计这些项目有多少是开放的,它们有四种类型:简单、中等、困难和不想要。所有这些类型都是 div 中的值。我需要从计数中排除 'Not-Wanted' 类型。请注意 'Open' 和 'Close' 值周围有不同数量的空格。这是 html 结构:
<table>
<tbody>
<tr>
<td>
<div>Difficult</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Closed </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Medium</div>
</td>
<td>Name</td>
<td>Open </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Medium</div>
</td>
<td>Name</td>
<td> Closed</td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td>Closed </td>
</tr>
<tr>
<td>
<div>Not-wanted</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Difficult</div>
</td>
<td>Name</td>
<td>Open</td>
</tr>
............
这是我解决问题的尝试之一。明明是错的,就是不知道怎么改正。
$doc = new DOMDocument();
$doc->loadHtmlFile('http://www.nameofsite.com');
$doc->preserveWhiteSpace = false;
$xpath = new DOMXPath($doc);
$elements = $xpath->query("/html/body/div[1]/div/section/div/section/article/div/div[1]/div/div/div[2]/div[1]/div[2]/div/section/div/div/table/tbody/tr");
$count = 0;
foreach ($elements as $element) {
if ($element->childNodes->nodeValue != 'Not-wanted') {
if ($element->childNodes->nodeValue === 'open') {
$count++;
}
}
}
echo $count;
我对 DOMXPath 有非常基本的了解,所以它对我来说太复杂了,因为我只能创建简单的查询。
有人可以帮忙吗?
提前致谢。
根据您示例中的数据,我认为您可以将 xpath 表达式调整为此以获得所有符合您条件的 <tr>
:
//table/tbody/tr[normalize-space(td[3]/text()) = 'Open' and td[1]/div/text() != 'Not-wanted']
$elements
是 DOMNodeList 类型,然后您可以获取 length
属性 以获取列表中的节点数。
例如:
$source = <<<SOURCE
<table>
<tbody>
<tr>
<td>
<div>Difficult</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Closed </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Medium</div>
</td>
<td>Name</td>
<td>Open </td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Medium</div>
</td>
<td>Name</td>
<td> Closed</td>
</tr>
<tr>
<td>
<div>Easy</div>
</td>
<td>Name</td>
<td>Closed </td>
</tr>
<tr>
<td>
<div>Not-wanted</div>
</td>
<td>Name</td>
<td> Open </td>
</tr>
<tr>
<td>
<div>Difficult</div>
</td>
<td>Name</td>
<td>Open</td>
</tr>
</tbody>
</table>
SOURCE;
$doc = new DOMDocument();
$doc->loadHTML($source);
$doc->preserveWhiteSpace = false;
$xpath = new DOMXPath($doc);
$elements = $xpath->query("//table/tbody/tr[normalize-space(td[3]/text()) = 'Open' and td[1]/div/text() != 'Not-wanted']");
echo $elements->length;
这将导致:
5