2009-12-14 61 views
3

假设我有这样的XML:这两种样式的xpath逻辑'和'等价吗?

<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> 

我想挑选出有Manufacturer子节点与UK@country产品的节点,但不具有的true一个@obsolete。我可以说,无论是

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

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

无一不让我我想要的节点。

我的问题是,这两种方法之间有什么功能差异和条件?有不同的方法可以产生不同的结果吗? (我知道and在更复杂的条件下起作用)在风格上,是比其他人更喜欢的吗?

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

回答

7

对于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] 
1

虽然有可能是他们是如何内部处理稍有差异,有你的两个陈述没有区别。同样,对于是否相互之间没有性能优势或推荐。

我个人比较喜欢第一个(and),因为它更容易告诉正在发生的事情,尤其是当你添加更多复杂的比较( S和 S)的组合。

5

它们之间的区别是:

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

只要你使用连词(逻辑“和”)把条件连在一起,结果是一样的。后者无法实现分离(逻辑“或”)。

还要注意的是多个谓词中定义它们的顺序处理,因此

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

装置“在英国被制造的那些的第二产品”,而

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

意味着“列表中的第二个产品,但仅当它在英国制造”