我有一个很大的XML。该XML的片段如下所示:
<div class="x-column-inner" id="ext-gen422" style="width: 850px;">
<div id="ext-comp-1206" style="width: 14px;" class=" x-column">
<div tabindex="-1" class="x-form-item x-hide-label" id="ext-gen434">
<label class="x-form-item-label" style="width:100px;" for="ext-comp-1180" id="ext-gen435"></label>
<div style="padding-left:105px" id="x-form-el-ext-comp-1180" class="x-form-element">
<div class="x-form-check-wrap" id="ext-gen436" style="width: 14px; height: 28px;">
<input type="checkbox" name="ext-comp-1180" id="ext-comp-1180" autocomplete="off" class=" x-form-checkbox x-form-field">
<label class="x-form-cb-label" for="ext-comp-1180" id="ext-gen437"> </label>
</div></div> <div class="x-form-clear-left">
</div>
</div>
</div>
<div id="ext-comp-1207" style="width: 150px;" class=" x-column">
<label id="ext-comp-1203" style="width: 140px;">Add to Watchlist</label>
</div>
<div id="ext-comp-1208" style="width: 107px;" class=" x-column">
我需要根据带有“添加到关注列表”文本的标签节点找到复选框类型的“输入”节点。
由于'input'和'label'节点位于不同的层次结构中,//语法似乎不起作用:
//div[label[contains(text(),'Add to Watchlist')]]
将只提供子标签的父div。 我试图从这个片段的最顶层节点开始
$x("//div[@class='x-column-inner' and //label[contains(text(),'Add to Watchlist')]]")
但是这给了6个可能的匹配。
注意:不能使用@id属性,因为这是动态分配给节点的,所以下次页面加载@id时会有所不同。 我不想使用position()谓词,因为这会使XPATH变为静态,而xpath可能会因位置的任何变化而中断。
答案 0 :(得分:0)
你可以尝试这样的东西,但它看起来非常贪婪......基本上它的作用是在input
标签的每个轴上搜索,看看是否有相关的label
标签。因此,对于每个input
,它会搜索其祖先,后代和兄弟姐妹。
肯定有一些更聪明的解决方案。
//input[@type = 'checkbox' and (@id = ancestor::label/@for or @id = descendant::label/@for or @id = following::label/@for or @id = preceding::label/@for)]
但是,如果您的代码段不匹配,则不会匹配input
代码,请考虑提供更好的代码段。它会提高答案的准确性。
编辑:这是添加“添加到关注列表”约束的(未经测试)方式。
//input[@type = 'checkbox' and (@id = ancestor::label[. = 'Add to Watchlist']/@for or @id = descendant::label[. = 'Add to Watchlist']/@for or @id = following::label[. = 'Add to Watchlist']/@for or @id = preceding::label[. = 'Add to Watchlist']/@for)]
但是再一次,这些xpath请求非常贪婪,并且不能保证与input
相关联的每个label
元素匹配,例如以下input
将不匹配这个片段:
<div>
<div>
<label for="id">Add to Watchlist</label>
</div>
<div>
<input type="checkbox" id="id" />
</div>
<div>
在一个xpath请求中可能有更高效的解决方案,但您应该考虑做几个请求
例如,一个请求使用“添加到关注列表”文本查找for
元素的每个label
属性值,然后执行另一个请求以查找关联的input
元素。
我还应该尝试将您的请求限制在范围内的基础form
元素。如果我找到时间,也许我会用更好的请求进行编辑。
编辑2 这是一个工作和更聪明的请求
//form//input[@type = 'checkbox' and @id = ancestor::form[1]//label[. = 'Add to Watchlist']/@for]
您可以将其面对此代码段
<html>
<form>
<label for="bar">Add to Watchlist</label>
<div>
<div>
<label for="id">Add to Watchlist</label>
</div>
<div>
<input type="checkbox" id="id" />
<input type="checkbox" id="foo" />
<input type="checkbox" id="bar" />
<input type="checkbox" />
<input type="checkbox" id="" />
</div>
</div>
</form>
<label for="foo">Add to Watchlist</label>
</html>
最重要的是,你了解它是如何工作的以及为什么它更好。请花点时间考虑一下。