php - 复杂的 Xpath 获取除某些特定类属性之外的所有值
问题描述
我有一个标记 HTML,如下所示:
<body>
<div>......</div>
............
<div class="entry-content">
<div class="code1 code2">(ads.....);</div>
<p><img src="https://www..."></img></p>
<h2> title </h2>
<div class="code1-block code2">(ads.....);</div>
<div class="data1 dta-ta1">
<ul><li><p> text</p></li>
<li><span> text2 </span></li>
<li><span> text3 </span></li>
<div class="codex1 code-block"><span>(ads ....); </span></div>
<li><span> text4 </span></li>
<div class="codex1 code-block"><span>(ads ....); </span></div>
</ul>
</div>
<div class="codex2-block code2">(ads.....);</div>
<div class="data2-entry dta-ta2">
<p>
<span> text5</span>
</p>
<p> text6 </p>
<p> text7 </p
<div class="codex1 code-block"><span>(ads ....); </span></div>
<li><span> text8 </span></li>
<div class="codex1 code-block"><span>(ads ....); </span></div>
</div>
</div>
</body>
我试图“进入 div 并class="entry-content"
从其子节点获取所有文本,不包括子节点class= "code1", "code2", "codex1", "codex2"
我的代码如下所示只是转到 div 并从子节点获取所有文本。但是,我无法使用 code1 和 code2 从子节点中删除文本。感谢您的支持。谢谢。
$classname='entry-content';
$a = new DOMXPath($dom);
$query = "//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]";
$list = $a->query($query);
if ($list->length > 0) {
foreach ($list as $element) {
$nodes = $element->childNodes;
foreach ($element as $node) {
$bodytext = trim(preg_replace('/[\r\n]+/', ' ', $node->nodeValue));
$bodyContent .= '<p>' . $bodytext . '</p>';
}
}
}
我的预期输出:
https://www ...
标题
文本2
文本3
文本4
文本5
文本6
文本7
文本8
解决方案
您的输入文档格式不正确,>
缺少a </p
,并且div
未正确关闭。输入文档固定后,工作路径表达式为
XPath 表达式
//div[@class='content']//text()[not(ancestor::div/@class[contains(., 'code')])][normalize-space()]
它选择所有文本节点,但前提是它们没有祖先div
元素class
的值包含“代码”的属性,并且选择的文本节点不能是纯空格。
输出
单个结果由 分隔------
:
title
-----------------------
text
-----------------------
text2
-----------------------
text3
-----------------------
text4
-----------------------
text5
-----------------------
text6
-----------------------
text7
-----------------------
text8
更新
我试过你的回答。它可以工作,但是我仍然需要来自 img 标签的来源。我怎么才能得到它?
也可以选择元素的source
属性img
,但这会使 Xpath 表达式更加复杂。您应该只添加另一行 PHP 来评估单独的路径表达式,例如:
//div[@class='entry-content']/p/img/@source
更新 2
虽然我绝对不建议使用这个表达式(因为它会混淆你的代码),但这里是如何使用联合运算符将两个表达式组合成一个表达式:
//div[@class='entry-content']//text()[not(ancestor::div/@class[contains(., 'code')])][normalize-space()] | //div[@class='entry-content']//p/img/@src
推荐阅读
- ruby - Rails 4, Ruby 2.7.1 schema.rb 显示“Could not dump table because of following FrozenError”
- c++ - 如何打印使用“std::any”类型的变量插入的字符串向量的元素
- mysql - Grafana 中的 Delta 与 MySQL DB
- linux - Manjaro(Arch 操作系统)中的终端命令推送 Github 项目
- switch-statement - 在 ArrayFormula 中使用 SWITCH 的 Google 表格。古怪的公式,寻找高效但更优雅的东西
- windows - Apache Common Daemons:PrunServ --StartPath 参数覆盖 Windows 上的 PATH
- python - python grpc客户端如何管理连接?
- c++ - 我正在尝试通过 for 循环在数组中输入值,但循环只取一个值并且程序已关闭
- mmap - msync 是否会因未更改的内存而产生成本?
- lua - 如何在 Lua 中按顺序(逐行/单线程)运行代码?