1

700 を超えるノードを持つ、かなり大きな RSS xml ファイルがあります。XMLReader Iterator ライブラリを使用して解析し、結果をページあたり 10 として表示しています。

これは、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 ファイル全体を解析してから、対応するページの結果を表示するだけであることです。 50 ノードまで。

データの表示に遅延が発生しています。要求されたページに対応するノードだけを読み取ることは可能ですか? したがって、最初のページでは、すべての xml ファイルを解析してから最初の 10 個のノードを表示する代わりに、1 から 10 の位置のノードを読み取ることができます。つまり、xml ファイルの解析中に制限を適用できますか?

同様の質問に対処するGordonのこの回答に出くわしましたが、SimpleXMLを使用しているため、大きなxmlファイルの解析にはお勧めできません。

4

4 に答える 4

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);
于 2013-09-14T10:03:54.370 に答える
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 ++;
}
于 2013-09-09T11:34:51.253 に答える