在Java中,如何正确确定XPath选择器是否定位属性或元素?
解释问题:我需要从WebDriver的WebElement获取文本。元素的innerText或它的属性取决于XPath。不幸的是,每次提取都是以不同的方式完成的(见下文)所以我必须首先确定预期目标是什么,元素或属性:
String getStringValue(String selector, WebElement context) {
if(targetsAttribute(selector) {
WebElement node = context.findElement(new By.xpath(elemPart(selector)));
return node.getAttribute(attrName(selector));
} else {
return context.findElement(new By.xpath(selector)).getText();
}
};
我正在寻找targetsAttribute
,elemPart
和attrName
方法的实施。目前我使用正则表达式:
Pattern ATTR_PAT = Pattern.compile("^.*/@([^/]+)$");
Pattern ELEM_PAT = Pattern.compile("^(.*)/@[^/]+$");
但我发现这种方法很丑陋而且非系统性。例如,它与attribute::
不匹配。有没有办法使用一些标准库左右这样做?
注意:我实际上是在尝试解决类似问题,如下面的问题,只是更高一点:
答案 0 :(得分:1)
您可以使用Saxon XSLT / XQuery处理器的XPath expression parser。
ExpressionParser的parseExpression()方法应该能够为您提供所需的信息。
如果你弄明白了,请发布你的代码(作为答案)因为我不知道其他人已经发布了解决方案。
实际上,对于每个XPath表达式,构建一个能够正确回答它是否会选择元素或属性的算法是不可能的。这是因为XPath表达式返回的结果类型可能取决于输入。例如。 XPath表达式
//foo | //bar/@baz
可以返回元素,属性,两者或两者,具体取决于文档中存在的元素和属性。
但是,使用上面提到的解析工具可能会让您最有可能找出XPath表达式的子集,是否可以返回属性。
在我看来,无论是否选择元素或属性,都无法获取XPath表达式的字符串值,这是WebDriver API中的一个严重缺点。除非它以其他方式提供我不知道的能力。
答案 1 :(得分:0)
缺少与节点无关的意味着解决文本内容是许多(如果不是全部!)XPath API中的问题。而且,正如已经指出的那样,没有完全通用的方法来预先确定XPath表达式是否选择属性或元素,因为它可以选择两者,并使用析取组合。
如果你可以排除析取(或者单独处理每一部分),那么,启发式地说,这一切都取决于表达式中最后的斜线后面的内容:如果剩余部分以' @' (或'属性::'),您正在选择一个属性;否则,一个元素。这不是防弹,但根据经验,我发现这在实践中已经足够好了。你的启发式方法与任何方法一样好。