假設我有一段這樣的 HTML:
<a>Ask Question<other/>more text</a>
我可以匹配這段XPath:
//a[text() = 'Ask Question']
或者...
//a[text() = 'more text']
或者我可以使用 dot 來匹配整個事情:
//a[. = 'Ask Questionmore text']
這篇文章描述了.(dot) 和之間的區別text(),但簡而言之,第一個回傳單個元素,后者回傳一個元素串列。但這就是我覺得有點奇怪的地方。因為 whiletext()可用于匹配串列中的任何一個元素,所以當涉及到 XPath 函式時,情況并非如此contains()。如果我這樣做:
//a[contains(text(), 'Ask Question')]
...我收到以下錯誤:
錯誤:contains() 的第一個引數的必需基數是一或零
text()在使用完全匹配(等于)時如何作業,但在部分匹配(包含)上不起作用?
uj5u.com熱心網友回復:
對于這個標記,
<a>Ask Question<other/>more text</a>
請注意,該a元素有一個文本節點子節點 ( "Ask Question")、一個空元素子other節點 ( "more text")和第二個文本節點子節點 ( )。
以下是//a[contains(text(),'Ask Question')]根據該標記進行評估時發生的情況的推理方法:
contains(x,y)期望x是一個字串,但text()匹配兩個文本節點。- 在XPath 1.0中,用于轉換多個節點為一個字串的規則是這樣:
通過回傳節點集中在檔案順序中排在第一位的節點的字串值,將節點集轉換為字串。如果節點集為空,則回傳空字串。[強調]
- 在XPath 2.0 中,向需要字串的函式提供一系列文本節點
contains(text(),'substr')是錯誤的,因此會導致多個匹配文本節點的錯誤。
在你的情況...
XPath 1.0 將
contains(text(),'Ask Question')視為contains('Ask Question','Ask Question')這是
true. 另一方面,請務必注意在 XPath 1.0contains(text(),'more text')中將評估為false。在不知道上面的 (1)-(3) 的情況下,這可能是違反直覺的。XPath 2.0 會將其視為錯誤。
更好的選擇
如果目標是查找
a字串值包含子字串的所有元素,則"Ask Question"://a[contains(.,'Ask Question')]這是最常見的要求。
如果目標是找到
a具有等于?? 的直接文本節點子節點的所有元素"Ask Question"://a[text()='Ask Question']這在希望從后代元素中排除字串時很有用,
a例如,如果您想要這個a,<a>Ask Question<other/>more text</a>但不是這個
a:<a>more text before <not>Ask Question</not> more text after</a>
也可以看看
- 如何
contains()處理節點集第一個 arg - 如何將 XPath contains() 用于特定文本?
- 在 XPath 中測驗 text() 節點與字串值
uj5u.com熱心網友回復:
原因是該contains函式不接受節點集作為輸入——它只接受一個字串。(嗯,它可能依賴于引擎,因為它適用于Python的lxml模塊。根據規范,它應該將集合中第一個節點的值轉換為字串并對其進行操作。另見XPath contains(text() ,'some string') 與具有多個文本子節點的節點一起使用時不起作用)
//a[text() = 'Ask Question']匹配a包含等于 的文本節點的任何元素Ask Question。
//a[text() = 'more text']匹配a包含等于 的文本節點的任何元素more text。
所以這兩個運算式都匹配相同的a元素。
您可以重新處理您的查詢,//a[text()[contains(., 'Ask Question')]]以便該contains方法一次僅作用于一個文本節點。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/355457.html
