php xpath оценить дубликаты данных, получить только первую строку

Это мой PHP-код:

<?php error_reporting(E_ALL); ini_set("display_errors",1); ini_set('max_execution_time', 36000); //300 seconds = 5 minutes $url = 'http://www.sportstats.com/soccer/matches/20170815/'; libxml_use_internal_errors(true); $doc = new DOMDocument(); $doc->loadHTMLFile($url); $xpath = new DOMXpath($doc); $data = array( 'HomeTeam' => $xpath->evaluate('string(//td[@class="table-home"]/a)'), 'AwayTeam' => $xpath->evaluate('string(//td[contains(@class, "table-away")]/a)'), 'FtScore' => $xpath->evaluate('string(normalize-space(translate(//td[@class="result-neutral"]," " ,"")))'), 'HomeTeamid' => $xpath->evaluate('substring-before(substring-after(substring-after(//td[@class="table-home"]/a/@href, "/soccer/"),"-"),"/")'), 'AwayTeamid' => $xpath->evaluate('substring-before(substring-after(substring-after(//td[@class="table-away"]/a/@href, "/soccer/"),"-"),"/")') ); foreach ($data as $key) { echo $data['HomeTeamid'].","; echo $data['HomeTeam'].","; echo $data['FtScore'].","; echo $data['AwayTeam'].","; echo $data['AwayTeamid']."<br/>"; } ?> 

Но сценарий дает повторяющиеся результаты:

 n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4 n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4 n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4 n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4 n3QdnjFB,Santos,0-0,Fluminense,EV9L3kU4 

Но я хочу, чтобы это выглядело …

  HTeamid,Santos,0-0,Fluminense,ATeamid HTeamid,Cartagena,1-0,Llaneros,ATeamid HTeamid,Cerro Porteno,1-1,Libertad Asuncion,ATeamid HTeamid,Operario,2-1,Maranhao,ATeamid HTeamid,Emelec,2-0,Fuerza,ATeamid ... .. . 

Совпадение списка изображений. Я просмотрел другие вопросы на сайте и не нашел ответа. Как мне получить все данные других команд с помощью команды echo (я не хочу делать с var_dump).

Вот две ошибки, вы используете //td в пути к местоположению. Это делает путь относительно документа, а функция строки всегда возвращает текстовое содержимое первого узла в списке. Вы всегда играете в первую игру.

Типичная структура для сбора данных списка:

 foreach($xpath->evaluate($exprForItems) as $item) { $detail = $xpath->evaluate($exprForDetail, $item); } 

Более конкретный пример:

 $document = new DOMDocument(); $document->loadHtml($html); $xpath = new DOMXpath($document); $expressions = new stdClass(); // this is the expression for items - it returns a node list $expressions->games = '//div[@id = "LS_todayMatchesContent"]/table/tbody/tr'; // this are detail expressions - they return a string $expressions->home = 'string(td[@class = "table-home"]/a)'; $expressions->homeId = 'substring-before(substring-after(substring-after(td[@class="table-home"]/a/@href, "/soccer/"),"-"),"/")'; $expressions->away= 'string(td[@class = "table-away"]/a)'; foreach ($xpath->evaluate($expressions->games) as $game) { var_dump( [ $xpath->evaluate($expressions->home, $game), $xpath->evaluate($expressions->homeId, $game), $xpath->evaluate($expressions->away, $game) ] ); } 

Вывод:

 array(3) { [0]=> string(6) "Santos" [1]=> string(8) "n3QdnjFB" [2]=> string(10) "Fluminense" } array(3) { [0]=> string(9) "Cartagena" [1]=> string(8) "6eofBSjQ" [2]=> string(8) "Llaneros" } //... 

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

Попробуйте изменить свой массив xpath следующим образом:

 'HomeTeam' => $xpath->query('//td[@class="table-home"]/a'), 'AwayTeam' => $xpath->query('//td[contains(@class, "table-away")]/a'), 'FtScore' => $xpath->query('//td[@class="result-neutral"]'), ... 

используя query и изменяя пути.

И тогда вы можете повторить свои результаты следующим образом:

 foreach ($data as $dataKey => $dataValue) { foreach ($dataValue as $key => $element) { $nodes = $element->childNodes; foreach ($nodes as $node) { $tag = $node->nodeValue; echo $dataKey.' - '.$key.' - '.$tag.'<br>'; //$dataKey and $key are just informative } } echo '<br>'; } 

Для меня он перечислил:

 HomeTeam - 0 - Santos HomeTeam - 1 - Cartagena HomeTeam - 2 - Cerro Porteno HomeTeam - 3 - Operario HomeTeam - 4 - Boca Juniors HomeTeam - 5 - Emelec .... AwayTeam - 0 - Fluminense AwayTeam - 1 - Llaneros AwayTeam - 2 - Libertad Asuncion AwayTeam - 3 - Maranhao AwayTeam - 4 - Gimnasia y Tiro AwayTeam - 5 - Fuerza A. .... 

Конечно, если вам нужен какой-то значимый отпечаток данных, вам нужно его собрать в массиве ….

Надеюсь, что это тот ответ, который вы ищете 🙂 У вас отличный день!