Select descendant elements that are not contained

2019-04-08 08:15发布

问题:

In XPath 1.0, how can I select all descendant nodes C of current (context) node A, that are not contained in an intervening node of type B?

For example, find all <a> links contained in the current element, that are not inside a <p>. But if the current element is itself inside a <p>, that's irrelevant.

<p>                   <—— this is irrelevant, because it's outside the current element
    ...
    <div>             <—— current element (context node)
        ...
        <a></a>       <—— the xpath should select this node
        ...
        <p>
            ...
            <a></a>   <—— but not this, because it's inside a p, which is inside context
            ...
        <p>
        ...
    </div>
    ...
</p>

The ... in the example could be several depths of intervening nodes.

I'm writing XSLT 1.0, so the additional functions generate-id(), current(), and such are available.

回答1:

This is one possible XPath :

.//a[not(ancestor::p/ancestor::* = current())]

This XPath checks if current descendant a element doesn't have ancestor p which ancestor is current context node. In other words, it checks if the a element doesn't have ancestor p intervening between the a and the current context node.