aa bb cc ee

XPath - get parent text of text nodes with condition

<doc ok="yes">
    <a>
        <b>
            <c>
                aa
                <d ok="yes">
                    bb
                </d>
                cc
            </c>
        </b>
    </a>
    <e>
        ee
    </e>
    <f ok="no">
        no
    </f>
</doc>

I need to get a list of nodes using XPath, where each node must satisfy the following conditions:

  • node has at least one child text node

  • if node (or the nearest node on the ancestor axis) has an attribute "ok", the value should be"yes"

  • when any ancestor is part of the result, exclude node

So, in my example, I would like to get <c>and <e>. node is <d>excluded because it is a child <c>that is part of the result.

I started with condition (1) using this expression //*[count(./text()[normalize-space()])>0]. He returns <c>, <d>, <e>and <f>. I do not know how to exclude<d>

+4
source share
1

2 . № 1 2.

//*[text()[normalize-space()]]
   [
      ancestor-or-self::*[not(@ok)] 
        or 
      ancestor-or-self::*[@ok][1][@ok='yes']
    ]

XML , xpath 3 : <c>, <d> <e>.

3. , , , ancestor::* node. not(), , № 1 2 ( , node ):

[not(
        ancestor::*[text()[normalize-space()]]
        [
            ancestor-or-self::*[not(@ok)] 
                or 
            ancestor-or-self::*[@ok][1][@ok='yes']
        ]
    )
]

, xpath:

//*[text()[normalize-space()]]
   [
      ancestor-or-self::*[not(@ok)] 
        or 
      ancestor-or-self::*[@ok][1][@ok='yes']
    ]
    [not(
            ancestor::*[text()[normalize-space()]]
            [
                ancestor-or-self::*[not(@ok)] 
                    or 
                ancestor-or-self::*[@ok][1][@ok='yes']
            ]
        )
    ]

([]) xpath, , № 1, 2 3.

+8

Source: https://habr.com/ru/post/1589188/


All Articles