Являются ли эти два стиля xpath логическими и эквивалентными? - PullRequest
3 голосов
/ 14 декабря 2009

Предположим, у меня есть xml вот так:

<Products>
  <Product name="Liquid Oxygen">
    <Manufacturer name="Universal Exports" country="UK" />
  </Product>
  <Product name="Hydrazine">
    <Manufacturer name="ACME Inc." country="USA" />
  </Product>
  <Product name="Gaseous Oxygen" obsolete="true">
    <Manufacturer name="Universal Exports" country="UK" />
  </Product>
  <Product name="Liquid Nitrogen">
    <Manufacturer name="Penguins R Us" country="Antarctica" />
  </Product>
</Products>

И я хочу выбрать узлы Product, которые имеют подузел Manufacturer с @country, равным UK, но не имеют @obsolete, равный true. Я могу сказать либо

/Products/Product[Manufacturer/@country = 'UK' and not(@obsolete = 'true)]

или

/Products/Product[Manufacturer/@country = 'UK'][not(@obsolete = 'true')]

и оба достают мне нужные мне узлы.

У меня вопрос: есть ли функциональная разница между этими двумя подходами к и-условиям? Есть ли ситуация, в которой разные подходы могут дать разные результаты? (Я понимаю, что and служит цели в более сложных условиях) Стилистически, один предпочтительнее другого?

(я использую C # и .NET 2.0, но я не верю, что это повлияет на ответ)

Ответы [ 4 ]

7 голосов
/ 14 декабря 2009

Для and в вашей ситуации они дают одинаковые результаты. Что касается стиля, выберите тот, который лучше выражает ваше намерение.

Однако, как только вы начнете использовать позиционные функции, такие как position(), count(), first() и last(), это будет иметь значение.

Убедитесь сами:

/Products/Product[Manufacturer/@country = 'UK' and (position() = 1)]

не возвращает ни одного узла, если первый товар в списке не из Великобритании, а:

/Products/Product[Manufacturer/@country = 'UK'][position() = 1]

вернет первый узел, соответствующий Великобритании как стране, и также может быть записан в краткой форме:

/Products/Product[Manufacturer/@country = 'UK'][1]
5 голосов
/ 14 декабря 2009

Разница между ними составляет:

  • первый вариант (… and …) - один предикат; оно должно быть выполнено целиком
  • второй вариант (…][…) - несколько предикатов; они оцениваются один за другим

Пока вы используете соединение (логическое «и»), чтобы связать условия, результат будет одинаковым. Разъединение (логическое «или») недостижимо для последнего.

Также обратите внимание, что несколько предикатов обрабатываются в порядке их определения, поэтому

/Products/Product[Manufacturer/@country = 'UK'][2]

означает «второй продукт, производимый в Великобритании» , тогда как

/Products/Product[Manufacturer/@country = 'UK' and position() = 2]

означает «второй продукт в списке, но только если он произведен в Великобритании» .

2 голосов
/ 14 декабря 2009

Инструмент XmlVisualizer (только для Windows / .NET) удобен для визуализации результатов xpath или для взлома с помощью xpath:

alt text

Бесплатный и открытый исходный код.

1 голос
/ 14 декабря 2009

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

Лично я предпочитаю первое (and), поскольку легче сказать, что происходит, особенно когда вы добавляете более сложные сравнения ( и с и или с) к смесь.

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