本文介绍在 PHP 中利用 DomXPath 的 XPath 表达式,同时获取 HTML 元素内子标签(如 、)和直接嵌入的纯文本节点(如 "Example Text 1"),确保文本与标签按 DOM 文档顺序自然混合返回。
本文介绍在 php 中利用 domxpath 的 xpath 表达式,同时获取 html 元素内子标签(如 ``、``)和直接嵌入的纯文本节点(如 `"example text 1"`),确保文本与标签按 dom 文档顺序自然混合返回。
在处理 HTML 结构时,DOM 树中 <p></p> 元素的子节点不仅包含元素节点(如 <span></span>、<img alt="如何使用 PHP DomXPath 提取标签内外的纯文本节点" >),还包含类型为 TEXT_NODE 的文本节点——它们是未被任何标签包裹的原始文本内容(即“裸文本”)。默认调用 $xpath->evaluate("*", $object) 仅匹配元素节点(* 表示任意元素),因此会遗漏 "Example Text 1" 和 "Example Text 2" 这类文本。
要一并捕获这些文本节点,需在 XPath 表达式中显式包含 text() 轴。text() 是 XPath 内置函数,用于选取当前上下文节点的直接子文本节点。通过联合运算符 |(union),可将两类节点合并查询:
$subObjects = $xpath->evaluate("*|text()", $object);该表达式等价于:“选取 $object 的所有子元素节点 或 所有直接子文本节点”,且返回结果严格遵循文档顺序(即 DOM 树中从左到右、深度优先的实际出现顺序)。
✅ 示例验证:
立即学习“PHP免费学习笔记(深入)”;
$html = <<<HTML
<p>
Example Text 1
<span> Text </span>
Example Text 2
<img src="example.png" alt="如何使用 PHP DomXPath 提取标签内外的纯文本节点" >
</p>
HTML;
$doc = new DOMDocument();
$doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($doc);
$p = $doc->getElementsByTagName('p')->item(0);
$subObjects = $xpath->evaluate("*|text()", $p);
foreach ($subObjects as $node) {
if ($node instanceof DOMText) {
echo "TEXT: '" . trim($node->textContent) . "'\n";
} else {
echo "ELEMENT: <" . $node->nodeName . ">\n";
}
}输出结果(保持原文档顺序):
TEXT: 'Example Text 1' ELEMENT: <span> TEXT: 'Example Text 2' ELEMENT: <img alt="如何使用 PHP DomXPath 提取标签内外的纯文本节点" >
⚠️ 注意事项:
-
text()仅匹配直接子文本节点,不递归匹配后代文本(如<span><em>inner</em></span>中的"inner"不会被text()匹配到); - 返回的
DOMText节点可能包含空白符(换行、缩进),建议用trim($node->textContent)清理; - 若需排除空白文本节点,可在 XPath 中增强过滤:
"*|text()[normalize-space()]"; -
evaluate()返回的是DOMNodeList,其遍历顺序即为 DOM 树中的自然顺序,无需额外排序。
掌握 *|text() 模式,是精准解析混合内容 HTML(如富文本段落、带内联元素的文案)的关键技巧,让文本与标签真正“平权”参与后续处理逻辑。



















