帶有邏輯AND的“HTML Agility Pack”XPath查詢


我正在嘗試在HTML文檔中找到一個表,前兩行包含3列文本。

我已經嘗試使用以下查詢,我想返回表格的前2行包含第一列中的文本的節點:

string xpath = @"//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]";
HtmlNode temp = doc.DocumentNode.SelectSingleNode(xpath);

週一,它無法正常工作。

這是一些示例HTML,這是我想要匹配的表:

string xpath = @"//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]";
HtmlNode temp = doc.DocumentNode.SelectSingleNode(xpath);

您注意到列1,3,5在前兩行中有文本。這就是我想要匹配的東西。

一般承認的答案

//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]

此XPath表達式存在許多問題

  1. //table//table選擇任何作為table後代的table 。但是,在提供的XML文檔中沒有嵌套表。

  2. table[//tr[1]//td[1]//*[contains(text(), *)] 。謂詞中的//tr是一個絕對的 Xpath表達式 - 它選擇整個文檔中的所有tr元素 - 不僅僅是在這個table元素為根的子樹中。你很可能想要.//tr而不是//tr

  3. //td[1]選擇任何作為其父級的第一個td子元素的td元素 - 但很可能只需要第一個後代td元素。如果是這樣,您需要使用此XPath表達式: (//td)[1]

  4. //*[contains(text(), *)]這將選擇其第一個文本節點子節點包含第一個元素子節點的字符串值的任何元素 - 但您只想驗證td是否具有後代文​​本子節點 -這可以正確選擇: td[.//text()]

結合所有這些問題的更正,您可能想要的是

//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]

或者,可以編寫一個等效但更容易理解且不易出錯的表達式,如下所示:

//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]




許可下: CC-BY-SA
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因