Как требовать, чтобы все узлы удовлетворяли предикату XPath, чтобы предикат возвращал true - PullRequest
1 голос
/ 11 июля 2019

Учитывая структуру, как показано ниже, в которой элемент RootFolder может содержать любое количество элементов Folder, включая вложенные элементы Folder, я хочу выбрать все элементы RootFolder, которые содержат хотя бы одного потомка * Элемент 1005 *, для которого все его предшественники Folder (если есть) имеют атрибут visible, установленный в значение true.

<Root>
  <!-- This should be included -->
  <RootFolder>
    <Folder visible="true">
      <File />
    </Folder>
    <Folder visible="false">
      <File />
    </Folder>
  </RootFolder>
  <!-- This should be included -->
  <RootFolder>
    <Folder visible="true">
      <Folder visible="true">
        <File />
      </Folder>
    </Folder>
  </RootFolder>
  <!-- This should not be included -->
  <RootFolder>
    <Folder visible="false">
      <File />
    </Folder>
  </RootFolder>
  <!-- This should not be included -->
  <RootFolder>
    <Folder visible="false">
      <Folder visible="true">
        <File />
      </Folder>
    </Folder>
  </RootFolder>
  <!-- This should not be included -->
  <RootFolder>
    <Folder visible="true">
      <Folder visible="false">
        <File />
      </Folder>
    </Folder>
  </RootFolder>
</Root>

Следующее выражение XPath не работает, потому что оно включает в себя два последних элемента RootFolder.

//RootFolder[descendant::File[ancestor::Folder[@visible='true']]]

Учитывая следующую цитату из раздела «Семантика предиката» в http://courses.ischool.berkeley.edu/i290-14/s05/lecture-7/allslides.html,, действительно ожидается, что приведенное выше выражение XPath работает так же, как и раньше. Так что, возможно, то, что я пытаюсь сделать, невозможно, но я просто хотел убедиться, что я что-то не упустил.

Предикаты приводят к значению выражения, которое преобразуется в boolean ... Набор узлов имеет значение true, если он не пустой.

Возможно ли то, что я пытаюсь достичь, используя предикат XPath или какое-либо эквивалентное выражение XPath? Является ли единственной альтернативой программно подтвердить, что все предки удовлетворяют условию?

Ответы [ 3 ]

1 голос
/ 12 июля 2019

Я думаю, что вы были близки в своей первой попытке. Я думаю, что вам просто нужно проверить File, у которого нет предка Folder, у которого атрибут visible установлен в false ...

//RootFolder[.//File[not(ancestor::Folder/@visible='false')]]

Или это, если вам все равно, какое значение visible, если оно не true ...

//RootFolder[.//File[not(ancestor::Folder[not(@visible='true')])]]
1 голос
/ 12 июля 2019

В XPath 2.0 вы можете использовать

//RootFolder[every $a in ancestor::* satisfies $a/@visible='true']

, что, вероятно, является самым ясным способом сказать это.

Если у вас есть только XPath 1.0, вы можете выразить его как двойнойотрицательный:

//RootFolder[not(ancestor::*[not(@visible='true')])]

т.е. найти каждый RootFolder, у которого нет предка, у которого нет @visible='true'.

Кстати, помогает определить, какая версия XPathвы используете, так как ответы на любой сложный запрос будут отличаться в зависимости от версии.

1 голос
/ 11 июля 2019

Вы можете использовать ниже xpath.

 //RootFolder[.//File[not(ancestor::Folder[@visible='false'])]]

Здесь проверяется, есть ли в корневой папке какая-либо папка с visible = false, а также проверяется, есть ли в папке файл.

Скриншот:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...