XPath:子体,但不是通过遍历此节点

XPath:子体,但不是通过遍历此节点,xpath,lxml,traversal,Xpath,Lxml,Traversal,我有一个节点树,坦率地说,这是一个混乱 |-... |-cat \-dog |- dog * | |- chicken | | \- cat ! | \- cat ! | \- cat ! | \- dog | |- cat | \- ... |- cat |- dog | \- cat \- ..

我有一个节点树,坦率地说,这是一个混乱

|-...
|-cat
\-dog
   |- dog *
   |   |- chicken
   |   |     \- cat !
   |   \- cat !
   |         \- cat !
   |             \- dog
   |                 |- cat
   |                 \- ...
   |- cat
   |- dog
   |   \- cat
   \- ...
既然我已经选择了带星号的“狗”节点,我怎么能只选择那些它是最近的“狗”祖先的猫(即那些有感叹号的猫)

同样地,我如何只获得节点的那些cat后代,而不必遍历另一个dog节点


我在lxml中工作,目前有一个糟糕的解决方案,即通过
drop\u tree()
-ing所有dog节点断开图形连接。

您可以使用EXSLT的set扩展:。它们可以在
lxml
中使用
namespaces={“set”:http://exslt.org/sets“}
在XPath表达式中

然后你可以做类似的事情

asteriskeddog.xpath("set:difference(.//cat, .//dog/cat)",
    namespaces={"set": "http://exslt.org/sets"})

意义“当前节点下的所有
cat
元素,但当前节点下的
dog
元素除外。”。我已经在一些微数据解析中使用了这种技巧,其中包含嵌套的
itemscope
itemprop
元素

,使用XPath是不可能的。XPath只能访问子树,不能修改子树或创建新的XML节点。您将不得不使用XQuery或XSLT来实现它。@JensErat我不打算修改树或创建新的XML节点;这只是我目前的(垃圾)实现,因为(目前)无法在纯XPath中选择节点。您需要修改某些内容,如果不是原始XML,则是(子树的)副本、新结果树或其他内容。您想删除生成的子树中不可能的部分。这看起来正是我需要的。