DOMDocument::getElementsByTagName: само X първи елементи

Имам следния код:

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$doc = new DomDocument;
$doc->preserveWhiteSpace = false;

if ($doc->loadHtml(curl_exec($ch)))
    $anchors = $doc->getElementById('comments')->getElementsByTagName('a');
?>

който търси през отдалечена страница във всички връзки (‹ a > таг) в коментарите div.

Бих искал тази функция да върне само първите 50 ‹ a > тагове, без да анализира целия div. Това възможно ли е ? И ако да, как?

Благодаря предварително.


person roberto06    schedule 05.05.2014    source източник
comment
Тъй като използвате DOMDocument, целият div вече е анализиран. Дори целият документ. ... php.net/LimitIterator   -  person hakre    schedule 08.05.2014


Отговори (1)


Използвайте XPath израз:

$elements = 50;

$doc = new DOMDocument;
$doc->loadHTML($html);

$xpath = new DOMXPath($doc);
$anchors = $xpath->query(
    sprintf('//div[@id="comments"]/a[position() <= %d]', $elements)
);

Демо

person Amal Murali    schedule 05.05.2014
comment
Как ще работи това? Има само един div с ID коментари, който може да съдържа над 10 000 връзки. РЕДАКТИРАНЕ: Отговорено преди да редактирате с бита XPath. ще го пробвам - person roberto06; 05.05.2014
comment
Бих предложил първо да проверите дължината на елемента на етикетите <a>, ако е над 50, след това направете цикъл до това, в противен случай отрежете до дължината му. - person Shankar Narayana Damodaran; 05.05.2014
comment
@roberto06 можете, разбира се, да използвате и „контрарешението“, но след това foreach над отговора getElementsByTagName('a'). - person giorgio; 05.05.2014
comment
@AmalMurali (донякъде) работи. Сега се сблъсквам с други проблеми: 1. Контейнерът не винаги е ‹ div ›, той може също да бъде ‹ul› или ‹ ol ›, между другото. Трябва да проверя контейнера с коментарите за id, независимо от името на етикета му. 2. Връзките рядко са директно в контейнера, често има друг subdiv или ‹ p › или друго. Как мога да извлека първите 50 връзки в контейнера, независимо от тяхната дълбочина? - person roberto06; 05.05.2014
comment
@roberto06: Тогава променете израза си на '//*[@id="comments"]/a[position() <= %d]'. - person Amal Murali; 05.05.2014
comment
@AmalMurali Благодаря, това реши проблема с контейнера. Все още обаче имам проблем, докато се опитвам да извлека връзки, независимо от тяхната дълбочина. Вижте тук: Демо - person roberto06; 05.05.2014
comment
@roberto06: Това е много различно от действителния ви проблем. Моля, публикувайте го като нов въпрос. - person Amal Murali; 05.05.2014
comment
Ще го направя. Благодаря за помощта. - person roberto06; 05.05.2014
comment
Не мога да гласувам за, нямам необходимата репутация. Жалко, много ми помогнахте. Както и да е, успях да разреша този последен проблем, изглежда, че просто трябваше да добавя скоби към '//*[@id="comments"]//a' и работи като чар, вижте тук: Демо - person roberto06; 05.05.2014