这是一个函数DOMDocument::saveHTML()。在当前的 php 版本中,这可以获取您想要保存为 html 的节点。要保存节点的内部 html,您必须保存每个子节点。
function getHtml($nodes) {
$result = '';
foreach ($nodes as $node) {
$result .= $node->ownerDocument->saveHtml($node);
}
return $result;
}
要获取节点,您可以使用 Xpath。 id很简单。
获取所有元素节点:
//*
具有 id 属性“内容”
//*[@id="content"]
仅使用第一个找到的节点,以防有人多次添加相同的 id。
//*[@id="content"][1]
获取子节点 - node() 包括元素、文本和其他几个节点
//*[@id="content"][1]/node()
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXpath($dom);
echo getHtml($xpath->evaluate('//*[@id="content"][1]/node()'));
class 属性稍微复杂一些。类属性是令牌列表,它们可以包含多个类名。这是匹配它们的技巧。 Xpath 函数 normalize-space() 将所有空白组转换为单个空格分隔符。在前面和末尾添加一个空格,你会得到一个类似" one two three " 的字符串。现在您可以检查" one " 是否是该字符串的一部分。在 Xpath 中:
规范化类属性:
normalize-space(@class)
在开头和结尾添加空格:
concat(" ", normalize-space(@class), " ")
检查它是否包含子字符串
contains(concat(" ", normalize-space(@class), " "), " title ")
用它来限制节点
//*[contains(concat(" ", normalize-space(@class), " "), " title ")][1]/node()
放在一起:
$html = <<<'HTML'
<html>
<title></title>
<body>
<h1 class="title">I am title</h1>
<div id="content">
i am the <b>content</b>.
</div>
</body>
HTML;
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXpath($dom);
function getHtml($nodes) {
$result = '';
foreach ($nodes as $node) {
$result .= $node->ownerDocument->saveHtml($node);
}
return $result;
}
// first node with the id
var_dump(
getHtml(
$xpath->evaluate('//*[@id="content"][1]/node()')
)
);
// first node with the class
var_dump(
getHtml(
$xpath->evaluate(
'//*[contains(concat(" ", normalize-space(@class), " "), " title ")][1]/node()'
)
)
);
// alternative - handling multiple nodes with the same class in a loop
$nodes = $xpath->evaluate(
'//*[contains(concat(" ", normalize-space(@class), " "), " title ")]'
);
foreach ($nodes as $node) {
var_dump(getHtml($xpath->evaluate('node()', $node)));
}
输出:https://eval.in/118248
string(40) "
i am the <b>content</b>.
"
string(10) "I am title"
string(10) "I am title"