簡體   English   中英

xpath //*[.="Foo"] 和 xpath //*["Foo"] 在謂詞中只有一個字符串有什么區別?

[英]What is the difference between the xpath //*[.="Foo"] and the xpath //*["Foo"] with only a string in the predicate?

在 iPython 中使用一種新的(對我而言)根據 xpath 中的文本選擇節點的方法進行一些測試。 (為清楚起見,省略了無關的行)

In [26]: from lxml import etree

In [41]: string = '''
    ...: <outer>
    ...:    <mid>
    ...:       <inner>Foo</inner>
    ...:    </mid>
    ...: </outer>
    ...: '''

In [43]: root = etree.fromstring(string)

In [44]: root.xpath('//inner[text()="Foo"]')
Out[44]: [<Element inner at 0x10a0387c0>]

In [45]: root.xpath('//inner[.="Foo"]')
Out[45]: [<Element inner at 0x10a0387c0>]

In [47]: root.xpath('//inner["Foo"]')
Out[47]: [<Element inner at 0x10a0387c0>]

到目前為止,這一切對我來說都是有意義的。 然而:

In [48]: root.xpath('//*[text()="Foo"]')
Out[48]: [<Element inner at 0x10a0387c0>]

In [49]: root.xpath('//*[.="Foo"]')
Out[49]: [<Element inner at 0x10a0387c0>]

In [50]: root.xpath('//*["Foo"]')
Out[50]: 
[<Element outer at 0x10a188200>,
 <Element mid at 0x10a01d6c0>,
 <Element inner at 0x10a0387c0>]

我曾期望第二個和第三個 xpath 通過匹配所有三個節點來產生相同的結果。 誰能解釋他們為什么不同?

規格

PredicateExpr 通過評估 Expr 並將結果轉換為 boolean 來評估。 如果結果是一個數字,如果數字等於上下文 position,則結果將被轉換為 true,否則將被轉換為 false; 如果結果不是數字,則結果將被轉換,就像通過調用 boolean function 一樣 因此位置路徑para[3]等價於para[position()=3]

(強調我的)。 因此

root.xpath('//*["Foo"]')

相當於

root.xpath('//*["Lemon Pie"]')

它不會測試您的<inner>節點的內容; 事實上,因為"Foo"是一個真實的文字,AFAIK它也相當於

root.xpath('//*')

正如 Barmar 所說,由於空格,第一個和第二個表達式不匹配<inner>以外的節點。 要獲得所有三個,修剪(或“規范化空間”,在 XPath 語言中):

root.xpath('//*[normalize-space()="Foo"]')

為了增加 Amadan 的答案,您的第一個和第二個表達式不等價。 兩個都會匹配

<Inner>Foo</Inner>

但它們對結構給出不同的結果,例如

<Inner><span>Foo</span></Inner>

或者

<Inner>Foo<nbsp/>Bar</Inner>

作為一般規則,當有人使用text()時,10 次中有 9 次應該將其更改為. .

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM