Как перечислить все элементы TD, содержащие SPAN?

Я пытаюсь разобрать сайт в C# с помощью Fizzler. Моя цель - получить этот элемент: /html/body/form/div[3]/div/div/div/div/div/table/tbody/tr[18]/td[2]/span (FireBug XPath).

Проблема в том, что номера TR и TD не являются фиксированными. Все, что я знаю, это то, что мне всегда нужно LAST span, в LAST TD, в LAST TR:)

Я пытался с этим, но все, что я получаю, это NULL:

HtmlWeb document = new HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = document.Load("http://websiteaddress.com/site-name.html");

HtmlNodeCollection tableDatas = doc.DocumentNode.SelectNodes("//table/tbody/tr/td/span").Last();

Это ТАБЛИЦА, которую я пытаюсь разобрать. Мне нужно только содержимое последнего промежутка в последнем тд последней строки.

<table id="ctl00_WebPartManager1_blablabla_ctl00_tblRates" cellspacing="5" cellpadding="5" rules="all" border="1" style="width:100%;">
                <tr>
                    <th></th><th><span>USD</span></th>
                </tr><tr>
                    <th></th><th><span>USA $</span></th>
                </tr><tr>
                    <th></th><th><span>1</span></th>
                </tr><tr>
                    <td><span>2014. 03. 03.</span></td><td><span>227,31 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 04.</span></td><td><span>226,79 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 05.</span></td><td><span>225,66 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 06.</span></td><td><span>225,03 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 07.</span></td><td><span>223,14 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 10.</span></td><td><span>224,63 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 11.</span></td><td><span>226,06 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 12.</span></td><td><span>226,53 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 13.</span></td><td><span>223,63 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 14.</span></td><td><span>225,74 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 17.</span></td><td><span>224,67 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 18.</span></td><td><span>224,65 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 19.</span></td><td><span>223,26 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 20.</span></td><td><span>225,94 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 21.</span></td><td><span>226,25 </span></td>
                </tr>
            </table>

Вот результат, который я получаю от метода document.load() (это немного испортилось):

    <table id="ctl00_WebPartManager1_blablabla_ctl00_tblRates" cellspacing="5" cellpadding="5" rules="all" border="1" style="width:100%;">
                <tr>
                    <th><th><span>USD</span>
                <tr>
                    <th><th><span>USA $</span>
                <tr>
                    <th><th><span>1</span>
                <tr>
                    <td><span>2014. 03. 03.</span><td><span>227,31 </span>
                <tr>
                    <td><span>2014. 03. 04.</span><td><span>226,79 </span>
                <tr>
                    <td><span>2014. 03. 05.</span><td><span>225,66 </span>
                <tr>
                    <td><span>2014. 03. 06.</span><td><span>225,03 </span>
                <tr>
                    <td><span>2014. 03. 07.</span><td><span>223,14 </span>
                <tr>
                    <td><span>2014. 03. 10.</span><td><span>224,63 </span>
                <tr>
                    <td><span>2014. 03. 11.</span><td><span>226,06 </span>
                <tr>
                    <td><span>2014. 03. 12.</span><td><span>226,53 </span>
                <tr>
                    <td><span>2014. 03. 13.</span><td><span>223,63 </span>
                <tr>
                    <td><span>2014. 03. 14.</span><td><span>225,74 </span>
                <tr>
                    <td><span>2014. 03. 17.</span><td><span>224,67 </span>
                <tr>
                    <td><span>2014. 03. 18.</span><td><span>224,65 </span>
                <tr>
                    <td><span>2014. 03. 19.</span><td><span>223,26 </span>
                <tr>
                    <td><span>2014. 03. 20.</span><td><span>225,94 </span>
                <tr>
                    <td><span>2014. 03. 21.</span><td><span>226,25 </span>

            </td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></th></th></tr></th></th></tr></th></th></tr></table>

Может кто-нибудь помочь мне, пожалуйста?

Большое спасибо!

2 ответа

Решение

В добавок к <tbody> элемент , представляемый браузером, а не HTML Agility Pack (поэтому вы вообще не получаете никаких результатов); использование [last() предикаты для доступа к последнему дочернему элементу в текущем элементе.

//table/tr[last()]/td[last()]/span[last()]

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

(//table/tr/td/span)[last()]

С помощью .Last(); в C# будет даже немного хуже, так как результирующий набор даже должен быть построен как массив C#, прежде чем опускать все, кроме последнего значения.

Ты можешь использовать last() вместо точной позиции элемента, чтобы получить последний элемент в наборе результатов:

//table/tr[last()]/td[last()]/span[last()]

Выше XPath получит последний <tr>, тогда ищи последний <td> в этом <tr>, тогда ищи последний <span> в этом <td>,

Если это не то, что вам нужно, я бы предложил опубликовать образец HTML, чтобы нам было легче понять проблему.

Другие вопросы по тегам