我试图在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
}
答案 0 :(得分:3)
这是一个工作版本,其中包含您在评论中提供的不同建议:
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);
显然,这种模式是无用的,因为你可以使用像contains
这样的可用XPATH字符串函数获得相同的结果。
答案 1 :(得分:1)
对于这样的简单任务 - 获取div
属性以class
开头并且包含post-
的{{1}}属性,您应该使用常规的简单XPath查询:< / p>
content
下面,
- $xp->query('//div[starts-with(@class,"post-") and contains(@class, "content")]');
- 获取所有//div
...
- div
- 具有以“post-”开头的“class”属性
- starts-with(@class,"post-")
- 和......
- and
- 在contains(@class, "content")
属性值中包含“content”子字符串。
要使用class
,您需要注册php:functionString
命名空间(包含php
)和PHP functions(注册它们都使用$xpath->registerNamespace("php", "http://php.net/xpath");
)。
对于复杂的scenrios,当您需要更深入地分析值时,您可能想要创建并注册自己的函数:
$xp->registerPHPFunctions();
然后在XPath内部:
function example($attr) {
return preg_match('/post-(content|[a-z]+)/i', $attr) > 0;
}
此处,$divs = $xp->query("//div[php:functionString('example', @class)]");
将functionString
属性的字符串内容传递给@class
函数,而不是对象(就像example
一样)。
请参阅IDEONE demo
另见一篇关于在Using PHP Functions in XPath Expressions中在XPath中使用PhpFunctions的好文章。