xpath - 改进 XPath-query 以正确区分文本节点
问题描述
我过去广泛使用 XPath。目前我面临一个问题,我无法解决。
约束
- 纯 XPath 1.0
- 没有辅助功能(例如没有“concat()”)
HTML标记
<span class="container">
Peter: Lorem Impsum
<i class="divider" role="img" aria-label="|"></i>
Paul Smith: Foo Bar BAZ
<i class="divider" role="img" aria-label="|"></i>
Mary: One Two Three
</span>
挑战
我想提取三个连贯的字符串:
- 彼得:Lorem Impsum
- 保罗·史密斯:Foo Bar BAZ
- 玛丽:一二三
XPath
以下 XPath 查询是我经过 HOURS 研究后得出的最好的查询:
XPath 查询 1
//span[contains(@class, "container")]
=> Peter: Lorem ImpsumPaul Smith: Foo Bar BAZMary: One Two Three
XPath 查询 2
//span[contains(@class, "container")]//text()
Peter: Lorem Impsum Paul Smith: Foo Bar BAZ Mary: One Two Three
问题
尽管之后可以使用 (PHP) 字符串函数对生成的字符串进行后处理,但我无法将其拆分为正确的三个块:我需要一个 XPath 查询,它使我能够正确区分文本节点。
是否可以在文本节点之间集成一些“人工分隔符”?
解决方案
您对 XPath 1.0 期望过高。XPath 1.0 本身可以帮助您在这里选择
- 一个字符串,或
- 一组文本节点
然后,您必须在 XPath 之外完成您的处理(正如 Mads 在评论中建议的那样)。
要了解您遇到的限制,您的第一个 XPath,
//span[contains(@class, "container")]
选择span
元素的节点集。XPath 1.0 运行的环境向您显示文档中单个此类节点的字符串值(一些变体):
Peter: Lorem ImpsumPaul Smith: Foo Bar BAZMary: One Two Three
但要清楚:您的 XPath 在span
这里选择元素的节点集,而不是字符串。
你的第二个 XPath,
//span[contains(@class, "container")]//text()
选择节点的text()
节点集。XPath 1.0 运行的环境显示每个选定节点的字符串值。text()
如果您可以使用 XPath 2.0,您可以直接在 XPath 中选择一个字符串序列,
//span[contains(@class, "container")]/text()/string()
或者你可以加入他们,
string-join(//span[contains(@class, "container")]/text(), "|")
并直接得到
Peter: Lorem Impsum
|
Paul Smith: Foo Bar BAZ
|
Mary: One Two Three
或者
string-join(//span[contains(@class, "container")]/text()/normalize-space(), "|")
要得到
Peter: Lorem Impsum|Paul Smith: Foo Bar BAZ|Mary: One Two Three
推荐阅读
- javascript - 如何使用 Javascript 和 Node js 从表单传递数组
- javascript - JS 和 HTML5 入门
- sql-server - MARS TDS 标头包含错误 - ASP.NET Core + EF Core 2.1.4 + Azure SQL Server
- android - 如何在 Fragment 中覆盖 OnItemSelected 方法
- java - 本地开发最佳实践:Java、Docker、Kubernetes
- sitemap.xml - 错误:自定义站点地图结构中的名称空间不正确
- ruby - 尝试在厨师食谱中包含模块时,Ruby 返回未初始化的常量错误
- php - PHP 函数包括 -> 网站未加载
- bash - 试图解决“找不到匹配的 mac 错误”,任何想法
- snowflake-cloud-data-platform - 哪个 Admin 表在雪花中有数据库名称