XPath найти узлы между двумя другими

mig-z

Client
Регистрация
05.12.2014
Сообщения
303
Благодарностей
71
Баллы
28
Уже 2 часа бьюсь, не могу победить. (((
Страница
Нужно взять все строки в разделе Футбол (которые между заголовками Футбол и Теннис)

Нашел инфу, как это сделать, но не понимаю как это к моему примеру применить, вот страница.

Пробовал так:
Код:
//tbody/tr[1]/
    following-sibling::tr/
        preceding-sibling::tr[
            preceding-sibling::script[2]
        ]
Но выделяет не то (

Помогите пожалуйста решить задачу методами xpath.
 

CSS

Client
Регистрация
22.05.2010
Сообщения
1 327
Благодарностей
663
Баллы
113
XML:
//table[@class='smallwnd3']//a/b[contains(.,'Soccer')]/ancestor::tbody[1]/script[2]/preceding-sibling::tr[@id]
 
  • Спасибо
Реакции: mig-z

mig-z

Client
Регистрация
05.12.2014
Сообщения
303
Благодарностей
71
Баллы
28
  • Спасибо
Реакции: CSS

mig-z

Client
Регистрация
05.12.2014
Сообщения
303
Благодарностей
71
Баллы
28
XML:
//table[@class='smallwnd3']//a/b[contains(.,'Soccer')]/ancestor::tbody[1]/script[2]/preceding-sibling::tr[@id]
Подскажите пожалуйста, почему не собирает элементы в список?
Код сниппета:
Код:
Tab tab = instance.MainTab;
if (tab.IsBusy) tab.WaitDownloading();
// get document
Document doc = tab.MainDocument;
// find element by attribute
HtmlElementCollection heCol = doc.FindElementsByXPath(@"//table[@class='smallwnd3']//a/b[contains(.,'Футбол')]/ancestor::tbody[1]/script[2]/preceding-sibling::tr[@id]");

//вытаскиваем атрибут innertext из каждого элемента
var data = heCol.AttributesToString("innerhtml").Split(new string[] {Environment.NewLine},0).ToList();

//закидываем всё в список
project.Lists["s_matches"].AddRange(data);
project.SendInfoToLog("Добавлено ["+data.Count+"] элементов");
 

CSS

Client
Регистрация
22.05.2010
Сообщения
1 327
Благодарностей
663
Баллы
113
Подскажите пожалуйста, почему не собирает элементы в список?
Код сниппета:
Код:
Tab tab = instance.MainTab;
if (tab.IsBusy) tab.WaitDownloading();
// get document
Document doc = tab.MainDocument;
// find element by attribute
HtmlElementCollection heCol = doc.FindElementsByXPath(@"//table[@class='smallwnd3']//a/b[contains(.,'Футбол')]/ancestor::tbody[1]/script[2]/preceding-sibling::tr[@id]");

//вытаскиваем атрибут innertext из каждого элемента
var data = heCol.AttributesToString("innerhtml").Split(new string[] {Environment.NewLine},0).ToList();

//закидываем всё в список
project.Lists["s_matches"].AddRange(data);
project.SendInfoToLog("Добавлено ["+data.Count+"] элементов");
Конструкция что вы описали - работать будет только для однострочных элементов, в вашем случае в блоке InnerHtml строк много, поэтому необходимо делать иначе:
C#:
List<string> data = new List<string>();

Tab tab = instance.MainTab;
if (tab.IsBusy) tab.WaitDownloading();
// get document
Document doc = tab.MainDocument;
// find element by attribute
HtmlElementCollection heCol = doc.FindElementsByXPath(@"//table[@class='smallwnd3']//a/b[contains(.,'Футбол')]/ancestor::tbody[1]/script[2]/preceding-sibling::tr[@id]");
//вытаскиваем атрибут innerhtml из каждого элемента
for(int i = 0; i < heCol.Count; i++)
{
    data.Add(heCol.Elements[0].InnerHtml);
}
//закидываем всё в список
project.Lists["s_matches"].AddRange(data);
project.SendInfoToLog("Добавлено ["+data.Count+"] элементов");
 

mig-z

Client
Регистрация
05.12.2014
Сообщения
303
Благодарностей
71
Баллы
28
Конструкция что вы описали - работать будет только для однострочных элементов, в вашем случае в блоке InnerHtml строк много, поэтому необходимо делать иначе:
C#:
List<string> data = new List<string>();

Tab tab = instance.MainTab;
if (tab.IsBusy) tab.WaitDownloading();
// get document
Document doc = tab.MainDocument;
// find element by attribute
HtmlElementCollection heCol = doc.FindElementsByXPath(@"//table[@class='smallwnd3']//a/b[contains(.,'Футбол')]/ancestor::tbody[1]/script[2]/preceding-sibling::tr[@id]");
//вытаскиваем атрибут innerhtml из каждого элемента
for(int i = 0; i < heCol.Count; i++)
{
    data.Add(heCol.Elements[0].InnerHtml);
}
//закидываем всё в список
project.Lists["s_matches"].AddRange(data);
project.SendInfoToLog("Добавлено ["+data.Count+"] элементов");
Он у меня почему то добавил 29 раз (именно столько строчек надо) одну и ту же первую строку.
 

CSS

Client
Регистрация
22.05.2010
Сообщения
1 327
Благодарностей
663
Баллы
113
Он у меня почему то добавил 29 раз (именно столько строчек надо) одну и ту же первую строку.
Небольшой косяк :D Я забыл Elements[0] тут поставить i, так правильно:
C#:
List<string> data = new List<string>();

Tab tab = instance.MainTab;
if (tab.IsBusy) tab.WaitDownloading();
// get document
Document doc = tab.MainDocument;
// find element by attribute
HtmlElementCollection heCol = doc.FindElementsByXPath(@"//table[@class='smallwnd3']//a/b[contains(.,'Футбол')]/ancestor::tbody[1]/script[2]/preceding-sibling::tr[@id]");

//вытаскиваем атрибут innertext из каждого элемента
for(int i = 0; i < heCol.Count; i++)
{
    data.Add(heCol.Elements[i].InnerHtml);
}
//закидываем всё в список
project.Lists["s_matches"].AddRange(data);
project.SendInfoToLog("Добавлено ["+data.Count+"] элементов");
 
  • Спасибо
Реакции: mig-z

mig-z

Client
Регистрация
05.12.2014
Сообщения
303
Благодарностей
71
Баллы
28
Небольшой косяк :D Я забыл Elements[0] тут поставить i, так правильно:
C#:
List<string> data = new List<string>();

Tab tab = instance.MainTab;
if (tab.IsBusy) tab.WaitDownloading();
// get document
Document doc = tab.MainDocument;
// find element by attribute
HtmlElementCollection heCol = doc.FindElementsByXPath(@"//table[@class='smallwnd3']//a/b[contains(.,'Футбол')]/ancestor::tbody[1]/script[2]/preceding-sibling::tr[@id]");

//вытаскиваем атрибут innertext из каждого элемента
for(int i = 0; i < heCol.Count; i++)
{
    data.Add(heCol.Elements[i].InnerHtml);
}
//закидываем всё в список
project.Lists["s_matches"].AddRange(data);
project.SendInfoToLog("Добавлено ["+data.Count+"] элементов");
Спасибо большое за помощь! Стучусь к вам в скайпе и написал в личку. У меня меркантильное предложение :-)
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)