提问人:Lobstersack 提问时间:5/10/2020 更新时间:5/13/2020 访问量:511
Xpath 在选择嵌套在 <td 中的 <spans>时出现问题>
Xpath issues selecting <spans> nested in <td>
问:
我正在尝试使用一个程序从许多 XHTML 文档中提取文本,该程序使用 Xpath 查询将文本映射到结构化表格中。XHTML 文档如下所示
<td class="td-3 c12" valign="top">
<p class="pa-4">
<span class="ca-5">text I would like to select </span>
</p>
</td>
<td class="td-3 c13" valign="top">
<p class="pa-2">
<span class="ca-0">some more text I want to select </span>
</p>
<p class="pa-2">
<span class="ca-0">
<br>
</br>
</span>
</p>
<p class="pa-2">
<span class="ca-5">text and values I don't want to select.</span>
</p>
<p class="pa-2">
<span class="ca-5"> also text and values I don't want to </span>
</p>
</td>
我能够按它们的类选择跨度并检索文本/值,但是它们不够唯一,我需要按表类进行过滤。例如,仅 SPAN 类 CA-0 中的文本是 TD 类 TD-3 C13 的子类
这将是<span class="ca-0">some more text I want to select </span>
我已经尝试了所有这些组合
//xhtml:td[@class="td-3 c13"]/xhtml:span[@class = "ca-0"]
//xhtml:span[@class = "ca-0"] //ancestor::xhtml:td[@class= "td-3 c13"]
//xhtml:td[@class="td-3 c6"]//xhtml:span[@class = "ca-0"]
答:
我不确定您的示例 xml 在多大程度上反映了您的实际 xml,但严格基于您的示例 xml(并且忽略您可能会遇到的可能的命名空间问题),以下 xpath 表达式:
//td[contains(@class,"td-3")]/p[1]/span/text()
选择
text I would like to select
some more text I want to select
评论
//xhtml:td[contains(@class,"td-3 c13")]/xhtm:p[1]/xhtm:span/text()
XDMP-TOOFEWARGS: (err:XPST0017) fn:contains(@class = "td-3 c13") -- Too few args, expected 2 but got 1
contains()
contains(@class,"td-3 c13")
contains
contains(@class = "td-3 c13")
=
,
(@class, "td-3 c13")
根据文档,为了支持命名空间,您应该编写如下内容(fn:...):
//*:td[fn:contains(@class,"td-3")]/*:p[1]/*:span
或者使用绑定命名空间:
node.xpath("//xhtml:td[fn:contains(@class,'td-3')]/xhtml:p[1]/xhtml:span", {"xhtml":"http://example.com/ns"})
这个表达式也应该有效(选择每个 td 元素的第一个 p 的第一个跨度):
//*:td/*:p[1]/*:span[1]
旁注 :
您的 XPath 表达式可以修复。Span 不是子代,而是后代,所以我们使用 .我们习惯于只保留第一个结果。//
()
(//xhtml:td[@class="td-3 c13"]//xhtml:span[@class = "ca-0"])[1]
(//xhtml:td[@class="td-3 c6"]//xhtml:span[@class = "ca-0"])[1]
替换为谓语://
[]
(//xhtml:span[@class = "ca-0"][ancestor::xhtml:td[@class= "td-3 c13"]])[1]
使用以下命令测试您的 XPath: https://docs.marklogic.com/cts.validIndexPath
评论
//td[@class="td-3"]
//td[@class="td-3 c13"]
@class=
//*:td[@class = "td-3"]/*:p[1]/*:span[1]
解决方案是//td[(@class ="td-3") and (@class = "c13)]/p/span
出于某种原因,它看到
<td class="td-3 c13">
作为单独的类,例如
<td class = "td-3" and class = "c13"
所以你需要这样对待它们
感谢 @E.Wiest 和 @JackFleeting 验证我并为我指明了正确的方向。
评论