我正在尝试使用php中的XPATH获取内容。
<div class='post-body entry-content' id='post-body-37'>
<div style="text-align: left;">
<div style="text-align: center;">
Hi
</div></div></div>
我正在使用下面的php代码来获取输出。
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$xpath->registerPhpFunctions('preg_match');
$regex = 'post-(content|[a-z]+)';
$items = $xpath->query("div[ php:functionString('preg_match', '$regex', @class) > 0]");
dd($items);
它返回如下输出
DOMNodeList {#580
+length: 0
}
div
属性的class
节点从post-
开始并包含content
,您应该使用常规的简单XPath查询:$xp->query('//div[starts-with(@class,"post-") and contains(@class, "content")]');
这里,-//div
-获取所有...的div
-starts-with(@class,"post-")
-具有以“ post-”开头的“ class”属性-and
-和...-contains(@class, "content")
-在class
属性值中包含“内容”子字符串。要使用
php:functionString
,需要注册php
命名空间(使用$xpath->registerNamespace("php", "http://php.net/xpath");
)和PHP functions(要使用$xp->registerPHPFunctions();
来注册它们)。对于复杂的场景,当您需要更深入地分析值时,您可能需要创建并注册自己的函数:
function example($attr) { return preg_match('/post-(content|[a-z]+)/i', $attr) > 0; }
然后在XPath中:
$divs = $xp->query("//div[php:functionString('example', @class)]");
[这里,functionString
将@class
属性的字符串内容传递给example
函数,而不是对象(与php:function
相同)。请参见IDEONE demo:
function example($attr) { return preg_match('/post-(content|[a-z]+)/i', $attr) > 0; } $html = <<<HTML <body> <div class='post-body entry-content' id='post-body-37'> <div style="text-align: left;"> <div style="text-align: center;"> Hi </div></div></div> </body> HTML; $dom = new DOMDocument; $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEFDTD); $xp = new DOMXPath($dom); $xp->registerNamespace("php", "http://php.net/xpath"); $xp->registerPHPFunctions('example'); $divs = $xp->query("//div[php:functionString('example', @class)]"); foreach ($divs as $div) { echo $div->nodeValue; }
另请参阅有关在Using PHP Functions in XPath Expressions的XPath中使用PhpFunctions的精彩文章。
libxml_use_internal_errors(true);
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
// you need to register the namespace "php" to make it available in the query
$xpath->registerNamespace("php", "http://php.net/xpath");
$xpath->registerPhpFunctions('preg_match');
// add delimiters to your pattern
$regex = '~post-(content|[a-z]+)~';
// search your node anywhere in the DOM tree with "//"
$items = $xpath->query("//div[php:functionString('preg_match', '$regex', @class)>0]");
var_dump($items);
显然,这种模式是无用的,因为您可以通过可用的XPATH字符串函数(例如contains
)获得相同的结果。