Как выбрать таблицу, содержащую определенное ключевое слово - c # - xpath - htmlagilitypack

c# html-agility-pack keyword select xpath

Вопрос

Мне нужно собрать информацию с страницы продукта, которая не имеет никакого класса или идентификатора. Я использую htmlagilitypack и c # 4.0.

На этом исходном коде страницы продукта есть много таблиц. Таблица цен содержит строку «KDV». Поэтому я хотел бы получить эту строку «KDV», содержащую таблицу. Как я могу это сделать ?

В xpath ниже были выбраны все таблицы, например

string srxPathOfCategory = "//table";
var selectedNodes = myDoc.DocumentNode.SelectNodes(srxPathOfCategory);

Код ниже выбирает таблицу, но начинается с большинства внешних таблиц. Мне нужно выбрать большую внутреннюю таблицу, содержащую данную строку

//table[contains(., ' KDV')]

c #, xpath, htmlagilitypack

Принятый ответ

Код ниже выбирает таблицу, но начинается с большинства внешних таблиц. Мне нужно выбрать большую внутреннюю таблицу, содержащую данную строку

Использование :

//table
    [not(descendant::table) 
   and 
     .//text()[contains(., ' KDV')]
    ]

Это выбирает любую table в документе XML, у которой нет table потомка, и у которого есть потомок потомков текста, который содержит строку " KDV" .

В общем случае указанное выше выражение может выбирать многие такие элементы table .

Если вы хотите, чтобы только один из них был выбран (скажем, первый), используйте это выражение XPath - обратите внимание на скобки :

   (//table
        [not(descendant::table) 
       and 
         .//text()[contains(., ' KDV')]
        ]
    )[1]

Помните : если вы хотите выбрать первый элемент someName в документе, использование этого (как в текущем принятом ответе) неверно:

//someName[1]

Это второй самый часто задаваемый вопрос в XPath (после того, как выбрать элементы с неподписанными именами в документе XML с пространством имен по умолчанию).

Вышеприведенное выражение фактически выбирает любой элемент someName в документе, который является первым дочерним элементом его родителя - попробуйте его.

Причина этого неинтуитивного поведения заключается в том, что оператор XPath [] имеет более высокий приоритет (приоритет), который // псевдо-оператор.

Правильное выражение, которое действительно выбирает только первый элемент someName (в любом XML-документе), если таковой существует:

(//someName)[1]

Здесь скобки используются для явного переопределения приоритета оператора XPath по умолчанию.


Популярные ответы

Там может быть более эффективный способ сделать это. Во всяком случае, это весь код, который я использовал для вашего дела, и он работает для меня:

        HtmlDocument doc = new HtmlDocument();
        string url = "http://www.pratikev.com/fractalv33/pratikEv/pages/viewProduct.jsp?pInstanceId=3138821";
        using (var response = (WebRequest.Create(url).GetResponse()))
        {
            doc.LoadHtml(new StreamReader(response.GetResponseStream()).ReadToEnd());
        }
        /*There is an bug in the xpath used here. Should have been 
          (//table/tr/td/font[contains(.,'KDV')])[1]/ancestor::table[2] 
          See Dimitre's answer for an explanation and an alternative / 
          more generic / (needless to say) better approach */
        string xpath = "//table/tr/td/font[contains(.,'KDV')][1]/ancestor::table[2]"; 
        HtmlNode table = doc.DocumentNode.SelectSingleNode(xpath);


Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему