【问题标题】:How to determine whether XPath targets (returns) attribute or element?如何确定 XPath 是针对(返回)属性还是元素?
【发布时间】:2014-12-04 13:03:52
【问题描述】:

在 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();
  }
};

我正在寻找targetsAttributeelemPartattrName 方法的实现。目前我使用正则表达式:

 Pattern ATTR_PAT = Pattern.compile("^.*/@([^/]+)$");
 Pattern ELEM_PAT = Pattern.compile("^(.*)/@[^/]+$");

但我发现这种方法丑陋且不系统。例如,它与 attribute:: 不匹配。有没有办法使用一些标准库来做到这一点?

注意:我实际上是在尝试解决与以下问题类似的问题,只是稍微高一点:

How to get the value of an attribute using XPath

【问题讨论】:

  • 一个术语:在 XML 和 XPath 中,元素和属性都是文档树中的节点。因此,您要问的是“属性或元素”,而不是“属性或节点”。因此,标识符 WebElement、findElement 等。不过,这是个好问题。

标签: java xpath webdriver


【解决方案1】:

您也许可以使用 XPath expression parser,它是 Saxon XSLT/XQuery 处理器的一部分。

ExpressionParser 的parseExpression() 方法应该能够为您提供所需的信息。

如果您确实弄清楚了,请发布您的代码(作为答案),因为我不知道其他人已经发布了解决方案。

编辑:

实际上,对于每个 XPath 表达式,无论是选择一个元素还是一个属性,构建一个能够正确回答的算法是不可能的。这是因为 XPath 表达式返回的结果类型可能取决于输入。例如。 XPath 表达式

//foo | //bar/@baz

根据文档中存在的元素和属性,可以返回元素和属性,也可以两者都不返回。

但是,使用上面提到的解析工具可能会给您最好的机会来确定 XPath 表达式的子集,它们是否可以返回属性。

在我看来,无论选择元素还是属性,都无法获取 XPath 表达式的字符串值,这是 WebDriver API 的一个严重缺陷。除非它以我不知道的其他方式提供这种能力。

【讨论】:

    【解决方案2】:

    缺乏与节点无关的方法来处理文本内容是许多(如果不是全部!)XPath API 的问题。而且,正如已经指出的那样,没有完全通用的方法可以预先确定 XPath 表达式是选择属性还是元素,因为它可以通过分离组合选择两者。

    如果您可以排除析取(或单独处理每个部分),那么启发式地,这完全取决于表达式中最后一个斜线后面的内容:如果余数以'@'(或'attribute::')开头,您正在选择一个属性;否则,一个元素。这不是万无一失的,但根据经验,我发现这在实践中已经足够好了。您的启发式方法和其他方法一样好。

    【讨论】:

    • 你能举例说明第一句话吗?例如,在 XSLT 中,无论是属性还是元素,获取节点的文本值都没有问题。 Javascript XPath 也没有问题,因为您可以检查 XPathResult 节点(它是一个 DOM 节点)的 nodeType 并相应地提取其值。
    • 我没有包括 XSLT,它具有 ...我的意思是一个通用或通用的 node.text_content() 方法,你不'不必检查节点的类型来执行适当的操作——该方法在内部做正确的事情——对于没有文本内容的节点类型,它也可能对空字符串软失效。你必须以不同的方式对待元素和属性——即“相应地” - 正是这里的限制。
    • 进一步考虑,我想你可能会反对我使用“问题”这个词——我承认这一点。我应该使用“不幸”或“不方便”之类的词,因为严格来说,这并不是真正的问题。很抱歉!
    • 不,我同意你的观点,即在 WebDriver 中出现这种限制时,它 一个问题。特别是因为,在 WebDriver 中,(显然)甚至没有一种可靠的方法来“相应地”处理元素和属性,因为您无法确定您正在处理哪种类型的节点。我会说在 Javascript 中它只是不方便,因为至少你可以在尝试提取它之前找出它是哪种类型的节点;并且该细节可以封装在一个函数中。我在您的回答中所质疑的是,许多(如果不是全部) XPath API 共享 WD 的限制。
    • 但我猜你的意思是,如果不是所有的 XPath API 都有 Javascript DOM 的不便之处:你必须检查结果的节点类型才能知道如何提取字符串值。我不同意这一点(我真的不知道;因此我最初的问题是给你的)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多