如何使XPath表达式更通用?

如何使XPath表达式更通用?,xpath,xpathnavigator,Xpath,Xpathnavigator,我有一个导航树的xpath表达式,其中包含一些可以添加的子分支: /html/body/div[@id='application-wrapper']/div/div[2]/div/div[3]/div/div[2]/div/div/div/div[3]/div/**div[1]**/div[1]/table/tbody/tr/td[2]/div[@id='gwt-uid-17']/a /html/body/div[@id='application-wrapper']/div/div[2]/di

我有一个导航树的xpath表达式,其中包含一些可以添加的子分支:

/html/body/div[@id='application-wrapper']/div/div[2]/div/div[3]/div/div[2]/div/div/div/div[3]/div/**div[1]**/div[1]/table/tbody/tr/td[2]/div[@id='gwt-uid-17']/a

/html/body/div[@id='application-wrapper']/div/div[2]/div/div[3]/div/div[2]/div/div/div/div[3]/div/**div[2]**/div[1]/table/tbody/tr/td[2]/div[@id='gwt-uid-58']/a

/html/body/div[@id='application-wrapper']/div/div[2]/div/div[3]/div/div[2]/div/div/div/div[3]/div/**div[3]**/div[1]/table/tbody/tr/td[2]/div[@id='gwt-uid-83']/a
我需要使它的一般性声明类似于下面给出的,但无法做到这一点

//div[@role='treeitem']/a[text()='Situation']/ancestor::table//div[1]//a
有人能给我们一些启示吗

根据评论更新


我可以在中看到3个子节点[div[1] 第一个表达式,第二个表达式中的div[2] 表达式和div[3]在第三个 因此,与其写到 div[100]我想把它作为div[%d] 但我不能这样做


您所需要的只是唯一标识所需节点的最短表达式。例如,表达式

//div[@id='gwt-uid-17']/a
相当于上面的第一行,因为ID是唯一的(假定)

如果你想在“情境”链接下定位链接,你可以试试

//a[text()='Situation']//table//a[1]

但是我需要查看XML以知道这是否正确。

您所需要的是唯一标识所需节点的最短表达式。例如,表达式

//div[@id='gwt-uid-17']/a
相当于上面的第一行,因为ID是唯一的(假定)

如果你想在“情境”链接下定位链接,你可以试试

//a[text()='Situation']//table//a[1]

但是我需要查看XML以知道这是否正确。

假设这是有效的XHTML,并且
id
实际上是唯一标识符,您不需要指定的
div
之上的任何层次结构,并且可以使用如下XPath表达式:

//div[@id='gwt-uid-17']/a
//div[@id='$theDivIWant']/a
根据您的语言绑定,您还可以在XPath表达式中使用变量,因此可以使用如下通用表达式:

//div[@id='gwt-uid-17']/a
//div[@id='$theDivIWant']/a

假设这是有效的XHTML,并且
id
实际上是唯一标识符,则不需要指定的
div
s之上的任何层次结构,并且可以使用如下XPath表达式:

//div[@id='gwt-uid-17']/a
//div[@id='$theDivIWant']/a
根据您的语言绑定,您还可以在XPath表达式中使用变量,因此可以使用如下通用表达式:

//div[@id='gwt-uid-17']/a
//div[@id='$theDivIWant']/a

如果
id
属性的值唯一标识元素,则选择这三个
a
元素的简短表达式为:

//div[@id='gwt-uid-17' or @id='gwt-uid-58' or @id='gwt-uid-83']/a
但是,评估
/
缩写可能会非常低效,因此不建议这样做

选择这三个
A
元素且效率更高的单个XPath表达式是

/html/body/div[@id='application-wrapper']/div/div[2]/div/div[3]
   /div/div[2]/div/div/div/div[3]/div/div[not(position() >3)]/div[1]
    /table/tbody/tr/td[2]
     /div[@id='gwt-uid-17' or @id='gwt-uid-58' or @id='gwt-uid-83']/a

如果
id
属性的值唯一标识元素,则选择这三个
a
元素的简短表达式为:

//div[@id='gwt-uid-17' or @id='gwt-uid-58' or @id='gwt-uid-83']/a
但是,评估
/
缩写可能会非常低效,因此不建议这样做

选择这三个
A
元素且效率更高的单个XPath表达式是

/html/body/div[@id='application-wrapper']/div/div[2]/div/div[3]
   /div/div[2]/div/div/div/div[3]/div/div[not(position() >3)]/div[1]
    /table/tbody/tr/td[2]
     /div[@id='gwt-uid-17' or @id='gwt-uid-58' or @id='gwt-uid-83']/a

请用英语解释你想要什么节点。最终,这将产生一个健壮的XPath表达式。我可以看到3个子节点[div[1]在第一个表达式中,div[2]在第二个表达式中,div[3]在第三个表达式中],因此我不想一直写到div[100]为止,而是想把它放在div[%d]中,但我无法这样做。我相信您不关心这些div,对吗?你需要某种链接。请准确解释你想提取的内容。我的意思是“框中所有链接都有‘价格’标题”。从Firebug XPath开始绝对是错误的做法。我一点也不在乎abt DIV。我想要的是一个泛型div,当我输入一个整数时,它会将我带到那个特定的子节点。请用英语解释您想要的节点。最终,这将产生一个健壮的XPath表达式。我可以看到3个子节点[div[1]在第一个表达式中,div[2]在第二个表达式中,div[3]在第三个表达式中],因此我不想一直写到div[100]为止,而是想把它放在div[%d]中,但我无法这样做。我相信您不关心这些div,对吗?你需要某种链接。请准确解释你想提取的内容。我的意思是“框中所有链接都有‘价格’标题”。从Firebug XPath开始绝对是错误的做法。我一点也不在乎abt DIV。我想要的是一个通用div,当我输入一个整数时,它会将我带到特定的子节点。问题是“高效”表达式将很容易中断,即使页面中不相关的部分发生更改。一般来说,我不推荐这种HTML解析策略。我认为这几乎就是答案。查看我对评论中的问题的更新。@Mark Thomas:您所指的解析实际上是屏幕抓取。任何XPath表达式只有在XML文档被完全解析(一次和永远)后才被计算。因此,不是“parisng”,而是“evaluation”--让我们从正确的基础开始…问题是“高效”表达式将很容易中断,即使页面中不相关的部分发生更改。一般来说,我不推荐这种HTML解析策略。我认为这几乎就是答案。查看我对评论中的问题的更新。@Mark Thomas:您所指的解析实际上是屏幕抓取。任何XPath表达式只有在XML文档被完全解析(一次和永远)后才被计算。所以,不是“比较”,而是“评估”——让我们从正确的基础开始。。。