我有以下 XPath 来匹配亚马逊页面中的作者姓名:
//div[@class='pTitle']/span[@class='small itemByline'] | //div[@class='pTitle']/span[not(text())]
这个 XPath 的第一部分匹配得很好,但是页面中的一些项目在 pTitle 类的 div 之后没有跨度,所以没有什么可以匹配的,但我想得到一个 '' 或其他东西, 要知道作者没有被发现而不是跳过它。我想第二个 XPath 无效,因为它不起作用...
例如,对于使用我正在构建的 XPath 的作者条目,以“A Ditadura”开头的 3 个标题应该返回“”。他们不是。它使上述 XPath 返回 179 个项目而不是 209 个。
这是我的 Python 模块代码的一部分 https://github.com/caio1982/Amazon-Wishlist (顺便说一句,感谢到目前为止所有的好答案,感谢你们,我学会了 XPath)。
为了提供信息,我尝试使用 Firefox 的 XPath Checker 扩展,并使用 Python (lxml) 实现它。
这听起来类似于 How do I return '' for an empty node's text() in XPath?但我不确定。
我怀疑答案可能是围绕 XPath 轴的某些东西和某种 [notcontains] 限制?
EDIT1:根据 Dimitre 的建议稍微改写一下……是否可以使用 –– 如果可以,您是否有 –– Becker 的 XPath 方法使用 lxml 的工作示例?
EDIT2:样本树和预期结果:
<html>
<body>
<h1>Title</h1>
<p>First Paragraph</p>
<p>Second paragraph: <span>value</span></p>
<p>Third paragraph: <span>value</span></p>
<p>Forth paragraph:</p>
</body>
</html>
XPath//p/span 相应地返回第二段和第三段的“值”字符串。没关系,但我正在寻找 4 个结果而不是 2 个,如下所示:
None
value
value
None
我知道//p/span 对此不起作用,因此我正在寻找一些字符串魔术、节点比较或条件等。
请您参考如下方法:
您可以使用像这样的 XPath 表达式:
concat(
//div[@class='pTitle']/span[@class='small itemByline'],
substring('UNKNOWN',
1 + 7*(boolean(//div[@class='pTitle']/span[@class='small itemByline'])
)
)
当这个 XPath 表达式被求值时,如果 //div[@class='pTitle']/span[@class='small itemByline'] 存在,那么它的字符串值(与生成空字符串)。
当//div[@class='pTitle']/span[@class='small itemByline']不存在时,则结果为字符串'UNKNOWN' -- 空字符串与 substring('UNKNOWN', 1+0) 连接。
这里我们使用的事实是,在 XPath 1.0 中,每当 bool 值是算术运算符的参数时,它首先会使用以下规则转换为数字:
number(true()) = 1
和
number(false()) = 0
更新:这是一个基于 XSLT 的验证,使用 OP 编辑 2 中的 XML 文档并生成完全想要的结果(相同的 XPath 表达式(仅更新索引)是评估 4 次并输出所有产生的值——每个都在单独的行上):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="(//node())[not(position() > count(//p))]">
<xsl:variable name="vPos" select="position()"/>
<xsl:value-of select=
"concat((//p)[position() = $vPos]/span,
substring('UNKNOWN',
1 +7*boolean((//p)[position() = $vPos]/span)
)
)
"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
当此转换应用于最新提供的 XML 文档时:
<html>
<body>
<h1>Title</h1>
<p>First Paragraph</p>
<p>Second paragraph:
<span>value</span>
</p>
<p>Third paragraph:
<span>value</span>
</p>
<p>Forth paragraph:</p>
</body>
</html>
XPath 表达式被求值 N (4) 次并生成该求值的结果——如我们所见,这些正是想要的结果:
UNKNOWN
value
value
UNKNOWN
