val*_*nko 6 html xpath dom css-selectors
标记示例:
<div class="post-content">
<p>
<moredepth>
<...>
<span class="image-container float_right">
<div class="some_element">
image1
</div>
<p>do not need this</p>
</span>
<div class="image-container float_right">
image2
</div>
<p>text1</p>
<li>text2</li>
</...>
</moredepth>
</p>
</div>
Run Code Online (Sandbox Code Playgroud)
最糟糕的是“图像容器”的深度可以在任何级别。
我尝试使用的 Xpath:
//div[contains(@class, 'post-content')]//*[not(contains(@class, 'image-container'))]
Run Code Online (Sandbox Code Playgroud)
我应该使用什么 Xpath 来排除“some_element”和任何深度的“image-container”的任何其他子元素以及“image-container”元素本身?
此示例中的输出应为:
<p>
<moredepth>
<...>
<p>text1</p>
<li>text2</li>
</...>
</moredepth>
</p>
Run Code Online (Sandbox Code Playgroud)
PS是否可以使用CSS进行这样的选择?
您可以应用 Kaysian 方法来获取集合的交集。你有两套:
A:从 下降的元素//div[contains(@class, 'post-content')],不包括当前元素(因为您不想要 root div):
//*[ancestor::div[contains(@class, 'post-content')]]
Run Code Online (Sandbox Code Playgroud)
B:从 下降的元素//*[not(contains(@class, 'image-container'))],包括当前元素(因为您要排除整个树,包括div和span):
//*[not(ancestor-or-self::*[contains(@class, 'image-container')])]
Run Code Online (Sandbox Code Playgroud)
这两组的交集是您问题的解决方案。Kaysian 方法的公式为:A [ count(. | B) = count(B) ]. 将其应用于您的问题,您需要的结果是:
//*[ancestor::div[contains(@class, 'post-content')]]
[ count(. | //*[not(ancestor-or-self::*[contains(@class, 'image-container')])])
=
count(//*[not(ancestor-or-self::*[contains(@class, 'image-container')])]) ]
Run Code Online (Sandbox Code Playgroud)
这将从您的示例代码中选择以下元素:
/div/p
/div/p/moredepth
/div/p/moredepth/...
/div/p/moredepth/.../p
/div/p/moredepth/.../li
Run Code Online (Sandbox Code Playgroud)
排除span与div不需要的类及其后代匹配的 和 。
然后,您可以向表达式添加额外的步骤,以准确过滤出您需要的文本或节点。
一旦路径表达式将 XML 片段返回给您,XPath 就不允许对其进行操作。因此,您不能选择moredepth:
//moredepth
Run Code Online (Sandbox Code Playgroud)
没有得到所有该元素节点的结果,包括您想要排除的所有后代节点:
<moredepth>
<span class="image-container float_right">
<div class="some_element">
image1
</div>
<p>do not need this</p>
</span>
<div class="image-container float_right">
image2
</div>
<p>text1</p>
<li>text2</li>
</moredepth>
Run Code Online (Sandbox Code Playgroud)
你能做的就是只选择 的子节点moredepth:
//div[contains(@class, 'post-content')]/p/moredepth/*[not(contains(@class,'image-container'))]
Run Code Online (Sandbox Code Playgroud)
这将产生(各个结果用 分隔-------):
<p>text1</p>
-----------------------
<li>text2</li>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3214 次 |
| 最近记录: |