我正在尝试从以下HEREDOC中的链接中检索文本。
$html = <<<EOT
<a class="details" href="/link.asp">$2,697.75</a>
<a class="details" href="/link.asp"><s>$150.00</s></a>
<a class="details" href="/link.asp"><font color="red" size="2"><b>Price: $125.00</b></font></a>
EOT;
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadhtml($html);
$xpath = new DOMXPath($dom);
$prices_nodeList = $xpath->query('//child::a[@class="details"]');
//$prices_nodeList = $xpath->query('//descendant::a[@class="details"]');
//$prices_nodeList = $xpath->query('//a[@class="details"]/descendant::text()');
foreach ($prices_nodeList as $price) {
$prices[] = $price->nodeValue;
}
echo("<p>prices</p>");
echo("<pre>");
print_r($prices);
echo("</pre>");
?>
分配给$ prices_nodeList的xpath查询
$prices_nodeList = $xpath->query('//child::a[@class="details"]');
似乎做我想要的,但我不认为我理解它是如何工作的。据我所知,它说“获取所有直接的子元素链接与类”细节“。但是后两个链接中的文字不是直接的孩子,所以我不确定为什么我不必使用
$prices_nodeList = $xpath->query('//descendant::a[@class="details"]');
这个(即$ prices_nodeList的第一个注释掉的值)也检索所有三个值。我想知道为什么他们都工作,我的查询是否真的是最好的方法。相比之下
$prices_nodeList = $xpath->query('//a[@class="details"]/descendant::text()');
也有效,但
$prices_nodeList = $xpath->query('//a[@class="details"]/child::text()');
只检索第一个值($ 2,697.75)而不是后两个(因为文本包含在元素中)。
答案 0 :(得分:2)
据我所知,它说'获取所有直接的子元素链接与类“细节”。
不,这意味着获取所有具有当前上下文节点的子类“详细信息”的链接。
上下文节点是上一步选择的节点。
//
是/descandant-or-self::node
的快捷方式。来自specification:
//
是/descendant-or-self::node()/
的缩写。例如,//para
是/descendant-or-self::node()/child::para
的缩写,因此将选择文档中的任何para元素(即使作为文档元素的para
元素也将由//para
选择文档元素节点是根节点的子节点);div//para
是div/descendant-or-self::node()/child::para
的缩写,因此会选择para
个孩子的所有div
个后代。
/descendant-or-self::node()
基本上选择每个节点。因此,查看child
或descendant
轴之间没有区别。
如果一个链接不是一个节点的子节点,那么它肯定是其后代之一的子节点,它也由//
选择。
答案 1 :(得分:1)
在XPath中,伪操作符//
(descendant-or-self::
轴的缩写)用于选择特定类型的所有节点,无论它们在输入树中的哪个位置。然后:
//child::a
与//a
和
//descendant::a
仍然相当于//a
您始终在文档中选择所有 a 节点,
。虽然:
//a/descendant::text()
,等于//a//text()
,表示选择 a 的所有后代文本节点,它与
//a/child::text()
,等于//a/text()
,表示选择 a 的所有子文本节点($2,697.75
仅 a 的子项,其他文本节点是后代。)
在XPath中,显式轴descendant-or-self::
和child::
很少使用和必要。第一个通常由//
代替。第二个隐含地应用于/
或//
/child::
或//child::
。