$document = new DOMDocument();
$document->loadHTML(
'<h4 class="m-b-0 text-dark synopsis"><p>This is the text I want.</p></h4>',
);
echo $document->saveHTML();
Warning: DOMDocument::loadHTML(): Unexpected end tag : h4 in Entity, line: 1 in /in/BTVAZ on line 4
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><h4 class="m-b-0 text-dark synopsis"></h4><p>This is the text I want.</p></body></html>
这可以通过一些加载标志来避免:
$document = new DOMDocument();
$document->loadHTML(
'<h4 class="m-b-0 text-dark synopsis"><p>This is the text I want.</p></h4>',
LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NOERROR
);
echo $document->saveHTML();
<h4 class="m-b-0 text-dark synopsis"><p>This is the text I want.</p></h4>
<!doctype html>
<html>
<head>
<title>p is not allowed in h4...</title>
</head>
<body>
<h4><p>...but can still be selected via XPath</p></h4>
</body>
</html>
XPath选择示例
$x("//h4/p")
[p]
$x("string(//h4/p)")
'...but can still be selected via XPath'
2条答案
按热度按时间lymnna711#
h4
不能包含p
。PHP DOMDocument将尝试修复HTML:这可以通过一些加载标志来避免:
class属性值由用空格分隔的标记组成。一个简单的
contains()
将匹配字符串,如果它是另一个类名的一部分。将它们与Xpath 1匹配。0,使用
normalize-space()
和concat()
。我们的想法是将属性值转换为{space}classOne{space}classTwo{space}
,并将它们与{space}classOne{space}
进行匹配。normalize-space(@class)
。concat(' ', normalize-space(@class), ' ')
[contains(concat(' ', normalize-space(@class), ' '), ' synopsis ')]
//*[contains(concat(' ', normalize-space(@class), ' '), ' synopsis ')]
string(//*[contains(concat(' ', normalize-space(@class), ' '), ' synopsis ')])
输出:
如果尝试获取多个节点,请删除Xpath中的字符串转换。表达式将返回一个节点列表。迭代节点并读取
$textContent
属性。它将包含所有子代文本节点的内容。xtupzzrd2#
h4
中的p
元素。更多详情请参阅@ThW的回答(+1)。*如果
选择所需的
h4
元素,然后将选择所需
h4
元素的子p
元素,并且将选择这些
p
元素的文本节点子节点。可以通过
string()
获取节点的字符串值:请注意,上面假设XPath 1。0(或者只有一个这样的
p
),其中将返回//h4/p
选择的节点集合的第一个节点的字符串值。将节点序列传递给string()
在XPath 2中是错误的。0和更高的,这里应该用途:如果可能有一个以上这样
p
,或者如果您希望返回所有此类
p
元素的字符串值。HTML示例
XPath选择示例