2013-09-04 9 views
1

У меня есть XML-файл xml, который довольно большой, с более чем 700 узлами. Я использую XMLReader Iterator library, чтобы разобрать его и отобразить результаты как 10 на страницу.как читать только часть xml-файла с php xmlreader

Это мой пример кода для синтаксического анализа XML:

<?php 
require('xmlreader-iterators.php'); 

$xmlFile = 'http://www.example.com/rss.xml'; 
$reader = new XMLReader(); 
$reader->open($xmlFile); 

$itemIterator = new XMLElementIterator($reader, 'item'); 
$items = array(); 

foreach ($itemIterator as $item) { 
    $xml  = $item->asSimpleXML(); 
    $items[] = array(
     'title'  => (string)$xml->title, 
     'link'  => (string)$xml->link 
    ); 
} 

// Logic for displaying the array values, based on the current page. 
// page = 1 means $items[0] to $items[9] 

for($i = 0; $i <= 9; $i++) 
{  
    echo '<a href="'.$items[$i]['link'].'">'.$items[$i]['title'].'</a><br>';  
} 
?> 

Но проблема заключается в том, что для каждой страницы, я разбирать весь файл XML, а затем просто отображать соответствующие результаты страницы, например: если страница равна 1, отображает от 1 до 10 узлов, а если страница 5, отображает от 41 до 50 узлов.

Это вызывает задержку отображения данных. Можно ли читать только узлы, соответствующие запрашиваемой странице? Итак, для первой страницы я могу читать узлы от 1 до 10 позиций, вместо того, чтобы анализировать весь XML-файл, а затем отображать первые 10 узлов. Другими словами, могу ли я применить ограничение при анализе xml-файла?

я наткнулся this answer из Гордона, затрагивающие подобный вопрос, но он использует SimpleXML, который не рекомендуется для разбора больших XML-файлов.

+0

дайте свой XML-файл URL –

+0

Это мой фактический файл XML: http://oar.icrisat.org/cgi/exportview/subjects/ s1 = 2E2/RSS2/s1 = 2E2.xml, который почти похож по структуре на URL-адрес фида Yahoo: http://sports.yahoo.com/mlb/teams/bos/rss.xml –

+0

, пожалуйста, проверьте мой ответ – ncm

ответ

2

использование array_splice для извлечения части массива

require ('xmlreader-iterators.php'); 

$xmlFile = 'http://www.example.com/rss.xml'; 
$reader = new XMLReader(); 
$reader->open($xmlFile); 

$itemIterator = new XMLElementIterator($reader, 'item'); 
$items = array(); 

$curr_page = (0 === (int) $_GET['page']) ? 1 : $_GET['page']; 

$pages = 0; 

$max = 10; 

foreach ($itemIterator as $item) { 
    $xml = $item->asSimpleXML(); 
    $items[] = array(
     'title' => (string) $xml->title, 
     'link' => (string) $xml->link 
); 
} 

// Take the length of the array 
$len = count($items); 

// Get the number of pages 
$pages = ceil($len/$max); 

// Calculate the starting point 
$start = ceil(($curr_page - 1) * $max); 

// return the portion of results 
$arrayItem = array_slice($items, $start, $max); 

for ($i = 0; $i <= 9; $i ++) { 
    echo '<a href="' . $arrayItem[$i]['link'] . '">' . $arrayItem[$i]['title'] . '</a><br>'; 
} 

// pagining stuff 

for ($i = 1; $i <= $pages; $i ++) { 

    if ($i === (int) $page) { 
     // current page 

     $str[] = sprintf('<span style="color:red">%d</span>', $i); 
    } else { 

     $str[] = sprintf('<a href="?page=%d" style="color:green">%d</a>', $i, $i); 
    } 
} 
    echo implode('', $str); 
+0

Работает лучше всего. –

1

Используйте кеш в этом случае, так как вы не можете разобрать частично XML.

1

Проверить это

<?php 
if($_GET['page']!=""){ 
    $startPagenew = $_GET['page']; 
    $startPage = $startPagenew-1; 
} 
else{ 
     $startPage = 0; 
    } 
    $perPage = 10; 
    $currentRecord = 0; 
    $xml = new SimpleXMLElement('http://sports.yahoo.com/mlb/teams/bos/rss.xml', 0, true); 

    echo $startPage * $perPage; 
     foreach($xml->channel->item as $key => $value) 
     { 
     $currentRecord += 1; 

     if($currentRecord > ($startPage * $perPage) && $currentRecord < ($startPage * $perPage + $perPage)){ 

     echo "<a href=\"$value->link\">$value->title</a>";  

     echo "<br>"; 

     } 
     } 
//and the pagination: 
//echo $currentRecord; 
     for ($i = 1; $i <= ($currentRecord/$perPage); $i++) { 
      echo("<a href='xmlpagination.php?page=".$i."'>".$i."</a>"); 
     } ?> 

Обновлено

Проверить эту ссылку

http://www.phpclasses.org/package/5667-PHP-Parse-XML-documents-and-return-arrays-of-elements.html

+0

Это работает для xml-файла, который содержит около 200 узлов. Но если я попробую этот код с большим XML-файлом (как это необходимо), я получаю внутреннюю ошибку сервера. –

1

Вы можете использовать Dom и Xpath. Это должно быть намного быстрее, поскольку Xpath позволяет вам выбирать узлы по их позиции в списке.

<?php 
$string = file_get_contents("http://oar.icrisat.org/cgi/exportview/subjects/s1=2E2/RSS2/s1=2E2.xml"); 


$dom = new DOMDocument('1.0', 'utf-8'); 
$dom->loadXML($string); 
$string = ""; 

$xpath = new DOMXPath($dom); 

$channel = $dom->getElementsByTagName('channel')->item(0); 

$numItems = $xpath->evaluate("count(item)", $channel); 
// get your paging logic 

$start = 10; 
$end = 20; 

$items = $xpath->evaluate("item[position() >= $start and not(position() > $end)]", $channel); 
$count = $start; 
foreach($items as $item) { 
    print_r("\r\n_____Node number $count "); 
    print_r($item->nodeName); 
    $childNodes = $item->childNodes; 
    foreach($childNodes as $childNode) { 
     print_r($childNode->nodeValue); 
    } 
    $count ++; 
} 
+0

Я пробовал этот код. Для большого XML-файла (700 элементов) даже это дает внутреннюю ошибку сервера. И должен быть ** break; ** после последнего заявления print_r. Кроме того, элементы печатаются несколько раз. –

+0

Какая ошибка внутреннего сервера вы получили? У вас есть код ошибки? –

+0

Print_r - это просто, чтобы показать вам, что можно сделать с различными узлами. Результаты зависят от фактического содержимого. –

Смежные вопросы