XPath expression with a condition for multiple ancestors

The application I'm developing gets an XML structure similar to the following:

<Root>
    <Valid>
        <Child name="Child1" />
        <Container>
            <Child name="Child2" />
        </Container>
        <Container>
            <Container>
                <Child name="Child3"/>
                <Child name="Child4"/>
            </Container>
        </Container>
        <Wrapper>
            <Child name="Child5" />
        </Wrapper>
        <Wrapper>
            <Container>
                <Child name="Child19" />
            </Container>
        </Wrapper>
        <Container>
            <Wrapper>
                <Child name="Child6" />
            </Wrapper>
        </Container>
        <Container>
            <Wrapper>
                <Container>
                    <Child name="Child20" />
                </Container>
            </Wrapper>
        </Container>
    </Valid>
    <Invalid>
        <Child name="Child7" />
        <Container>
            <Child name="Child8" />
        </Container>
        <Container>
            <Container>
                <Child name="Child9"/>
                <Child name="Child10"/>
            </Container>
        </Container>
        <Wrapper>
            <Child name="Child11" />
        </Wrapper>
        <Container>
            <Wrapper>
                <Child name="Child12" />
            </Wrapper>
        </Container>
    </Invalid>
</Root>

I need to get a list of children under the following conditions:

  • The child is n descendant of the generation of the ancestor Real .
  • A child can be m a descendant of the Container generation , which is o a descendant of the Valid generation .
  • The valid ancestors for the Child element are the Container elements as the m generation of ancestors and the Real element as the ancestor of the first generation.

m, n, o - .

XPath

Valid/Child
Valid/Container/Child
Valid/Container/Container/Child
Valid/Container/Container/Container/Child
...

XPath.

XPath name, Child1, Child2 > , Child3 Child4.

.

Valid/Child | Valid//*[self::Container]/Child

name, Child19 Child20.

XPath , , self , Valid?

+3
2

//Child[ancestor::*
          [not(self::Container)][1]
                            [self::Valid]
       ]

XPath XML-:

<Root>
    <Valid>
        <Child name="Child1" />
        <Container>
            <Child name="Child2" />
        </Container>
        <Container>
            <Container>
                <Child name="Child3"/>
                <Child name="Child4"/>
            </Container>
        </Container>
        <Wrapper>
            <Child name="Child5" />
        </Wrapper>
        <Wrapper>
            <Container>
                <Child name="Child19" />
            </Container>
        </Wrapper>
        <Container>
            <Wrapper>
                <Child name="Child6" />
            </Wrapper>
        </Container>
        <Container>
            <Wrapper>
                <Container>
                    <Child name="Child20" />
                </Container>
            </Wrapper>
        </Container>
    </Valid>
    <Invalid>
        <Child name="Child7" />
        <Container>
            <Child name="Child8" />
        </Container>
        <Container>
            <Container>
                <Child name="Child9"/>
                <Child name="Child10"/>
            </Container>
        </Container>
        <Wrapper>
            <Child name="Child11" />
        </Wrapper>
        <Container>
            <Wrapper>
                <Child name="Child12" />
            </Wrapper>
        </Container>
    </Invalid>
</Root>

:

<Child name="Child1"/>
<Child name="Child2"/>
<Child name="Child3"/>
<Child name="Child4"/>

:

//Child[ancestor::*
          [not(self::Container)][1]
                            [self::Valid]
       ]

Child , , Container, Valid.

+4
//Valid
 //Child[count(ancestor::Container[ancestor::Valid])
          = count(ancestor::*[ancestor::Valid])]

:

//Valid//Child

Child, Valid.

count(ancestor::Container[ancestor::Valid]])

Container, node (Child), , Valid

count(ancestor::*[ancestor::Valid])

, node (Child), Valid

, Valid Child Container.

, Valid, .. /Valid/Valid/Child .

: xml , ?

//Valid//Child[not(ancestor::Wrapper)]
+3

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


All Articles