Xpath для исключения узлов после совпадения - PullRequest
3 голосов
/ 14 июля 2011

Я пытаюсь проанализировать некоторые данные, которые имеют каждую ячейку вкладок в узле <text />. Мне нужно игнорировать узлы, которые начинаются со звездного символа *, а также 4 узла после него. Можно ли это сделать с помощью xpath или мне нужно сделать это по-другому?

РЕДАКТИРОВАТЬ : мой XML выглядит следующим образом:

<page>
    <text attr="123" attr2="1234">ROW 1 CELL 1</text>
    <text attr="123" attr2="1234">ROW 1 CELL 2</text>
    <text attr="123" attr2="1234">ROW 1 CELL 3</text>
    <text attr="123" attr2="1234">ROW 1 CELL 4</text>
    <text attr="123" attr2="1234">ROW 1 CELL 5</text>
    <text attr="123" attr2="1234">* ROW 2 CELL 1</text>
    <text attr="123" attr2="1234">ROW 2 CELL 2</text>
    <text attr="123" attr2="1234">ROW 2 CELL 3</text>
    <text attr="123" attr2="1234">ROW 2 CELL 4</text>
    <text attr="123" attr2="1234">ROW 2 CELL 5</text>
    <text attr="123" attr2="1234">ROW 3 CELL 1</text>
    <text attr="123" attr2="1234">ROW 3 CELL 2</text>
    <text attr="123" attr2="1234">ROW 3 CELL 3</text>
    <text attr="123" attr2="1234">ROW 3 CELL 4</text>
    <text attr="123" attr2="1234">ROW 3 CELL 5</text>
</page>

Ответы [ 2 ]

4 голосов
/ 14 июля 2011

Следующее выражение:

 /*/text[not(starts-with(., '*')) and 
         not(preceding::*[position()<5][starts-with(., '*')])]

Выбирает следующее против вашего ввода:

<root>
  <text attr="123" attr2="1234">ROW 1 CELL 1</text>
  <text attr="123" attr2="1234">ROW 1 CELL 2</text>
  <text attr="123" attr2="1234">ROW 1 CELL 3</text>
  <text attr="123" attr2="1234">ROW 1 CELL 4</text>
  <text attr="123" attr2="1234">ROW 1 CELL 5</text>
  <text attr="123" attr2="1234">ROW 3 CELL 1</text>
  <text attr="123" attr2="1234">ROW 3 CELL 2</text>
  <text attr="123" attr2="1234">ROW 3 CELL 3</text>
  <text attr="123" attr2="1234">ROW 3 CELL 4</text>
  <text attr="123" attr2="1234">ROW 3 CELL 5</text>
</root>

Все ROW 2 пропущено.

Следующее выражение эквивалентно (по законам де Моргана):

/*/text[not(starts-with(., '*') or 
            preceding::*[position()<5][starts-with(., '*')])]
1 голос
/ 14 июля 2011

Это будет работать для вас

//text[starts-with(.,"*")]/preceding-sibling::text 
| //text[starts-with(.,"*")]/following-sibling::text[position() > 4]

Для предоставленного ввода это возвращает желаемые узлы

<text attr="123" attr2="1234">ROW 1 CELL 1</text>
<text attr="123" attr2="1234">ROW 1 CELL 2</text>
<text attr="123" attr2="1234">ROW 1 CELL 3</text>
<text attr="123" attr2="1234">ROW 1 CELL 4</text>
<text attr="123" attr2="1234">ROW 1 CELL 5</text>
<text attr="123" attr2="1234">ROW 3 CELL 1</text>
<text attr="123" attr2="1234">ROW 3 CELL 2</text>
<text attr="123" attr2="1234">ROW 3 CELL 3</text>
<text attr="123" attr2="1234">ROW 3 CELL 4</text>
<text attr="123" attr2="1234">ROW 3 CELL 5</text>

Однако, как указывает @lwburk в комментариях, это не работает для общегослучай, если у вас есть несколько узлов, которые начинаются с *.Это связано с тем, что оператор | в паре с двумя операторами завершает выбор всего до и после обоих соответствующих узлов.Его решение правильно обрабатывает обе ситуации.

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