这两种样式的xpath逻辑'和'等价吗?

Aak*_*shM 3 .net xpath

假设我有这样的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>
Run Code Online (Sandbox Code Playgroud)

我想挑选出有一个产品节点Manufacturer子节点用@countryUK,但不具有@obsoletetrue.我也可以说

/Products/Product[Manufacturer/@country = 'UK' and not(@obsolete = 'true)]
Run Code Online (Sandbox Code Playgroud)

要么

/Products/Product[Manufacturer/@country = 'UK'][not(@obsolete = 'true')]
Run Code Online (Sandbox Code Playgroud)

并且都得到了我想要的节点.

我的问题是,这两种方法和条件之间是否有任何功能差异?是否存在不同方法可能产生不同结果的情况?(我意识到and在更复杂的条件下有目的)风格上,一个比另一个更受欢迎?

(我正在使用C#和.NET 2.0,但我不认为这会对答案有任何影响)

Luc*_*ero 7

对于and您的情况,他们给你相同的结果.至于风格,选择更能表达你意图的风格.

然而,一旦你开始使用定位功能,如position(),count(),first()last(),但它确实有所作为.

你自己看:

/Products/Product[Manufacturer/@country = 'UK' and (position() = 1)]
Run Code Online (Sandbox Code Playgroud)

如果列表中的第一个产品不是来自英国,则不会返回任何节点,而:

/Products/Product[Manufacturer/@country = 'UK'][position() = 1]
Run Code Online (Sandbox Code Playgroud)

将返回与UK匹配的第一个节点作为国家/地区,也可以以简短形式编写:

/Products/Product[Manufacturer/@country = 'UK'][1]
Run Code Online (Sandbox Code Playgroud)


Tom*_*lak 5

他们之间的区别是:

  • 第一个variant(… and …)是一个谓词; 它必须作为一个整体来实现
  • 第二个变体(…][…)是多个谓词; 他们被一个接一个地评估

只要您使用连词(逻辑"和")将条件联系在一起,结果就是一样的.后者无法实现分离(逻辑"或").

另请注意,多个谓词按其定义的顺序进行处理,因此

/Products/Product[Manufacturer/@country = 'UK'][2]
Run Code Online (Sandbox Code Playgroud)

意思是"在英国生产的第二种产品",而

/Products/Product[Manufacturer/@country = 'UK' and position() = 2]
Run Code Online (Sandbox Code Playgroud)

表示"列表中的第二个产品,但仅限于在英国生产".