通过xpath弹性搜索元素?

时间:2011-01-05 21:05:09

标签: xpath

来自我之前的问题,

how does this xpath behave?

我找到了

html//p//table//tr//td/a

可以处理上述xpath之间出现的任何意外元素。

例如上面的xpath可以处理:

html/p/div/table/tr/td/a
html/p/table/tr/td/b/div/a

但是,我如何制定一个完全适应缺失/意外元素的xpath?

例如,开头提到的xpath无法处理以下内容:

/html/table/tr/td/a (p is missing)
/html/div/span/table/tr/td/a (p is missing and position replaced with `div/span/`)

是否存在xpath语法来处理上述情况?如果没有,那么替代方法是什么?

我的直觉告诉我,单独使用xpath是不可能的,所以我使用伪代码使用以下算法。

基本上,它将做的是拆分给定的xpath,并为每个祖先寻找直接的孩子。如果预期的孩子不存在或是其他元素,它将挖掘当前祖先的所有孩子,并尝试发现预期的孩子。

function searchElement(){
elements[] =  "/html/p/table/tr/td/a".split("/");
thisElement = "";

for (element in elements) {
if (firstItem){ 
  thisElement = findElementByXpath(element);
}else{
try{
thisElement.findElementByXpath(element); //look for this element inside previous element (from previous iteration);
}catch(NotFoundException e){ //if element is not found, search all elements inside previous element, and look for it.

foundElement = false;
discoveredElement = thisElement.findElementByXpath("*");
while(foundElement != true){

  if (discoveredElement.findEleemntByXpath(element) != null){
    //successful, element found, overwrite.
     thisElement = thisElement.findElementByXpath("*").findEleemntByXpath(element);
     foundElement = true;
  }else{
    //not successful, keep digging.
    discoveredElement = discoveredElement.findElementByXpath("*");
  }

}
}
}
}

return thisElement;
}

这是最佳方法吗?我担心搜索“*”并挖掘每个元素是相当低效的。

我不知道除了“xpath”之外还要标记这个问题...随意编辑。

谢谢。

2 个答案:

答案 0 :(得分:1)

这是可能的,但这是一个非常糟糕的主意。

//构造意味着“跳过任意数量的元素”。因此,您可以使用//td路径在DOM中的任何位置查找“td”元素。

这意味着您将在/html/body/im/not/what/you/want/td

处选择元素

答案 1 :(得分:1)

如果我理解正确,您希望选择具有特定有序可选祖先的a元素。

然后你的表达:/html//p//table//tr//td/a

应该是:

//a[(self::*|parent::td)[1]
       [(self::*|ancestor::tr)[1]
           [(self::*|ancestor::table)[1]
               [(self::*|ancestor::p)[1]
                        [ancestor::html[not(parent::*)]]
               ]
           ]
       ]
   ]

但这与:

相同
/html//a |
/html//td/a |
/html//tr//a |
/html//tr//td/a |
/html//table//a |
/html//table//td/a |
/html//table//tr//a |
/html//table//tr//td/a |
/html//p//a |
/html//p//td/a |
/html//p//tr//a |
/html//p//tr//td/a |
/html//p//table//a |
/html//p//table//td/a |
/html//p//table//tr//a |
/html//p//table//tr//td/a |

/html//a非常通用,可以选择任何a