И и ИЛИ с XPath. Запрос только в дочерних узлах, проверка всех узлов для дочерних элементов, соответствующих запросу - PullRequest
0 голосов
/ 05 декабря 2011

Допустим, у меня есть XML-структура, подобная этой:

<s>
  <a>
    <b id="myid">value1</b>
    <c id="test">val1</c>
    <c id="test2">valX</c>
  </a>
  <g>
    <d id="myid">value2</d>
    <e id="test">val2</e>
  </g>
  <i id="myid">value3</i>
  <j id="test">val3</j>
</s>

Обратите внимание, что имена тегов не важны.Только атрибут "id" и текстовое значение узла.

Запрос xpath будет использоваться для проверки существования значений, поэтому я могу вернуть весь XML.Этот запрос xpath выполняется для целого набора различных строк XML, возвращая тех, кто соответствует.

Теперь я хочу использовать xpath, чтобы проверить:

("myid"="value1" AND "test"="val1") OR ("myid"="value2" AND "test"="val2")

Как бы янаписать это как строку XPath?«val1» должен быть на том же уровне в XML, что и «value1».То же самое касается «val2» с «value2», а также «val3» и «value3»

Мне нужно написать это таким образом, чтобы облегчить расширение, так как этот запрос XPath будет сгенерирован кодом,

Входной запрос для генератора будет на И / ИЛИ с "(" и ")".Поэтому мне нужно сделать парсер для создания XPath из этого.

Примеры:

q1: ("myid"="value1" AND "test"="val1") OR ("myid"="value2" AND "test"="val2") OR 
 ("myid"="value3" AND "test"="val3")
q2: ("myid"="value1" AND "test"="val1") AND ("myid"="value2" AND "test"="val2") 
q3: "myid"="value1" AND ("test"="val1" OR "test"="valX") 

Мне нужен способ убедиться, что все проверки @id выполняются в одном и том же подмножестве XML.Таким образом, в этом XML проверка должна получить либо совпадение со всеми @ id непосредственно под S-узлом, либо совпадение со всеми @ id непосредственно под A-узлом, либо совпадение со всеми @ id непосредственно под G-узел.(и все другие подобные узлы)

Если какое-либо совпадение выполнено, я могу вернуть XML.Я не знаю, сколько существует уровней, так как xml очень универсален с одним правилом, согласно которому каждый узел значения имеет атрибут @id с именем значения.

"myid"="value1" AND "test"="val1" should return a match.
"myid"="value2" AND "test"="val2" should return a match.
"myid"="value3" AND "test"="val3" should return a match.
"myid"="value3" AND "test"="val1" should NOT return a match.
"myid"="value2" AND "test"="val3" should NOT return a match.

и т. Д.

Это может быть просто.Но я не нашел способ сделать это.Кто-нибудь может мне с этим помочь.Любые намеки приветствуются.

Надеюсь, я сделал это понятным.

Как бы вы написали то же самое, когда верхний или нижний регистр игнорируется.Как это?

//*[ *[@id [lower-case(.)="myid"] [lower-case(..)="value1"] ] and *[@id [lower-case(.)="test"] [lower-case(..)="val1"] ] ]

или есть способ получше.Значения предварительно .ToLower () 'ed.

1 Ответ

1 голос
/ 05 декабря 2011

Я думаю, что вы ищете такое выражение:

//*[ *[@id ='myid'] = 'value1' and *[@id ='test'] = 'val1']

Результатом будут все элементы, которые имеют как минимум двух дочерних элементов с атрибутом id со следующими ограничениями:

  • один из дочерних элементов должен иметь значение атрибута id, равное myid, значение элемента должно быть value1.
  • один из дочерних элементов должен иметь значение атрибута id, равное test, значение элемента должно быть val1.

Затем вы можете добавить and или or по своему желанию. Например:

//*[ (*[@id ='myid'] = 'value1' and *[@id ='test'] = 'val1') or (*[@id ='myid'] = 'value2' and *[@id ='test'] = 'val2')]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...