如何为动态层次结构下的节点编写XPATH
我得到了一个大的XML。该XML的一个片段如下所示:如何为动态层次结构下的节点编写XPATH,xpath,Xpath,我得到了一个大的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">
<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">
将只给出子标签的父div。
我试图从这个片段的最顶端节点开始
$x("//div[@class='x-column-inner' and //label[contains(text(),'Add to Watchlist')]]")
但这是6种可能的匹配
注意:@id属性无法使用,因为这将动态分配给节点,所以下次页面加载@id时会有所不同。
我不想使用position()谓词,因为这会使XPATH保持静态,XPATH可能会因位置的任何更改而中断。您可以尝试类似的方法,但它看起来非常贪婪。。。基本上,它所做的是在
输入
标记的每个轴上搜索,以查看是否存在关联的标签
标记。因此,对于每个输入
,它都会搜索其祖先、后代和兄弟姐妹。
当然还有一些更聪明的解决方案
//input[@type = 'checkbox' and (@id = ancestor::label/@for or @id = descendant::label/@for or @id = following::label/@for or @id = preceding::label/@for)]
但是,你的代码片段并不有趣,没有代码>输入< /代码>标签,请考虑提供一个更好的代码片段。这将提高答案的准确性
编辑:以下是一种(未经测试的)添加“添加到观察列表”约束的方法//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请求非常贪婪,并且不能保证匹配与标签
关联的每个输入
元素,例如,以下输入
在该代码段中不匹配:
<div>
<div>
<label for="id">Add to Watchlist</label>
</div>
<div>
<input type="checkbox" id="id" />
</div>
<div>
你可以面对这个片段
<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>
加入观察名单
加入观察名单
加入观察名单
最重要的是,你知道它是如何工作的,为什么它更好。请花点时间考虑一下。您的输入和文档中的标签标签之间可能存在什么关系?另外,您想检索标签还是输入标签?似乎只有逻辑关系,因为标签是输入标签。我无法解释句法关系:(不考虑你的例子格式不正确,他们看起来是兄弟姐妹,所以有些事情你没有告诉我们。为错误的缩进道歉。我已经更正了一点。请原谅我的代码段。给出更大的代码段(即此代码段的超集)会更好吗?我没有添加太大的代码段,因为这会使问题变得更复杂sy.还有什么其他想法可以让代码片段更好地提高答案的准确性吗?谢谢。你应该创建一个简单的代码片段,其中一些
输入
节点将与xpath表达式匹配。你尝试过我的答案吗?谢谢Zoom。你的解决方案已经将节点缩小到xml中的两个复选框中。两个节点是:
>
现在,由于这两个节点都没有任何唯一的属性,除了dynamic@id之外,我需要求助于position()吗?我不明白您需要实现什么。找到的两个input
标记已被选中,因为它们链接到另一个标签
标记,该标签具有for
属性,该属性与input
标记的id
属性匹配。这是您想要的吗?感谢您的时间和帮助。实际上我只想要input
节点,该节点附加到特定的标签
上,具有文本添加到监视列表
,因此我将xpath修改为://输入[@type='checkbox'和(@id=concenter::label/@for或@id=following sibling::label/@for或@id=previous sibling::label/@for)和(following::label='Add to Watchlist'))
它成功了:)
//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>