我让我的测试用例变得更加困难:
<div id="mw-content-text"><h2><span class="mw-headline" >CIA</span></h2>
<ol>
<li><small>Military</small> Central <a href="/Intelligence_Agency.html">Intelligence Agency</a>.</li>
<li>Culinary <a href="/Institute.html">Institute</a> of <a href="/America.html">America</a>.<br/>Renowned cooking school.</li>
</ol>
</div>
我有相同的目标,即提取:
- 中央情报局
- 美国烹饪学院
我可以选择性地选择排除哪些标签吗?
我已经尝试过(用于删除“军事”):
id('mw-content-text')/ol/li[not(self::small)]
但该条件适用于整个“li”节点,因此不受影响。
如果我做类似的事情
id('mw-content-text')/ol/li/*[not(self::small)]
然后我只过滤孩子,即使我成功地扔掉了“军事”,我也扔掉了“中央”、“烹饪”,即来自父母的文字。
我已经理解树是这样的:
div -- li
-- small -- Military
-- Central
-- a -- Intelligence Agency
-- li
-- Culinary
-- a -- Institute
-- of
-- a -- America
-- br
-- Renowned cooking school.
那是对的吗?有没有办法说“li 的文本元素和 li 的后代,除了 small 的后代?” '...除了 br 元素和所有后续文本元素'怎么样?
同样,使用(部分)Pythonic 解决方案也是可以接受的,但首选 XPath。
在坐下来阅读 Erik Ray 的“Learning XML, Second Edition”的第 6 章“XPath 和 XPointer”之后,我想我已经掌握了它。我想出了以下公式:
id('mw-content-text')/ol/li//text()[not(parent::small) and not(preceding-sibling::br)]
在这种情况下,似乎不可能连接文本节点的结果节点集。当我们简单地将“li”元素提供给字符串函数时,生成的字符串值只是元素节点 li 的后代的串联。但是在这种情况下,我们需要做进一步的过滤,这样我们就会得到一个节点集(符合条件的文本节点)而不是单个元素节点。关于连接节点集,可以在此处找到一个有用的 SO 问题:XPath to return string concatenation of qualifying child node values
任何建议如何改进此解决方案?