使用 XMLReader 获取 XML 代码计数 [英] Get XML code count using XMLReader

查看:21
本文介绍了使用 XMLReader 获取 XML 代码计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解析提供给 Google 商家的产品 Feed.问题是我希望它更具交互性,所以我使用了一个将 XML 转换为数组的函数,然后向用户显示更新了多少产品的百分比.我已经读到 XMLReader 比其他解析技术更有效.
如何使 XMLReader 更有效.我可以使用 XMLReader 获取节点数吗?或者我如何迭代 XML 使其响应更快.

I am trying to parse product feed that is provided to Google merchant. The thing is I want it to be more interactive so I was using a function that convert XML to array and then show percentage to the user that how much products are updated. I have read that XMLReader is much more efficient then other parsing techniques.
How can I make XMLReader more effective. Can I get number of nodes using XMLReader. Or how Can I iterate over XML that it can be more responsive.

推荐答案

将 XML 转换为数组是错误的想法.这将意味着您在内存中构建数据结构.但是您已经有了一个数据结构,因此将其转换为数组将意味着您松散 数据和功能.始终直接读取 XML 并使用它.

Converting the XML to an array is the wrong idea. It will mean that you build the data structure in memory. But you already have a data structure, so converting it into an array will mean that you loose data and features. Always read the XML directly and use it.

这里有几种方法可以归档您想要的内容.如果提要很小,您可以直接使用 DOM.这允许您使用 XPaths count() 函数.

Here are several ways to archive what you want. If the feed is small you can use DOM directly. That allows you to use XPaths count() function.

Google Product-Feed 基于 RSS 2.0 或 Atom 1.0.Atom 是更好的格式,所以让我们使用它.

The Google Product-Feed is bases on RSS 2.0 or Atom 1.0. Atom is the better format so let's use that.

// create a DOM document and load the XML 
$dom = new DOMDocument();
$dom->loadXml($xml);

// Create a xpath object and register prefixes for the two namespaces
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$xpath->registerNamespace('gi', 'http://base.google.com/ns/1.0');

// Output the entry count
var_dump($xpath->evaluate('count(//atom:entry)'));

// iterate the entries
foreach ($xpath->evaluate('//atom:entry') as $entry) {
  // output some data from them
  var_dump(
    [
      'title' => $xpath->evaluate('string(atom:title)', $entry),
      'summary' => $xpath->evaluate('string(atom:summary)', $entry),
      'image-link' => $xpath->evaluate('string(gi:image_link)', $entry)
    ]
  );
}

如果产品 Feed 非常大,则可能无法将其完全加载到内存中.但是要获得计数,您必须将它们加载到内存中或迭代它们两次.一种可能的方法是文件大小.当然,这不会是确切的进展.不过应该够用了.

If the product feed is really large, loading it completely into memory might not be working. But to get the count you will have to load them into memory or iterate them twice. One possible approach around that would be the file size. It will not be the exact progress of course. But should be good enough.

$file = 'feed.xml';
$fileSize = filesize('feed.xml');
$readBytes = 0;

// get an xml reader for the file
$reader = new XMLReader;
$reader->open($file);

// get an xml document, xpath and register the namespaces
$dom = new DOMDocument();
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$xpath->registerNamespace('gi', 'http://base.google.com/ns/1.0');

// look for the first entry element
while ($reader->read() && $reader->localName !== 'entry') {
  continue;
}

// while you have an entry element
while ($reader->localName === 'entry') {
  // import the entry into the prepared document
  $entry = $reader->expand($dom);
  var_dump(
    [
      'title' => $xpath->evaluate('string(atom:title)', $entry),
      'summary' => $xpath->evaluate('string(atom:summary)', $entry),
      'image-link' => $xpath->evaluate('string(gi:image_link)', $entry)
    ]
  );

  $readBytes += strlen($reader->readOuterXml());
  printf(
    'Read %s of %s bytes, %d%%',
    $readBytes,
    $fileSize,
    round($readBytes * 100 / $fileSize)
  );

  // move to the next entry sibling
  $reader->next('entry');
}

请注意,使用 XML Reader 会变慢.计算状态也会影响性能.仅显示已阅读的条目数量可能是一个更好的主意.

Be aware that using XML Reader will be slower. Calculating the status will cost performance, too. It might be a better idea just to show how many entries have been read.

这篇关于使用 XMLReader 获取 XML 代码计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆