我正在尝试解析提供给Google商家的产品Feed。问题是我希望它更具交互性,所以我使用的函数将XML转换为数组,然后向用户显示百分比产品的更新百分比。
我已经读过XMLReader
比其他解析技术更有效率
如何使XMLReader
更有效。我可以使用XMLReader获取节点数。或者我如何迭代XML以使其更具响应性。
答案 0 :(得分:1)
将XML转换为数组是错误的想法。这意味着您在内存中构建数据结构。但是您已经拥有了数据结构,因此将其转换为数组意味着您松散数据和功能。始终直接阅读XML并使用它。
以下是存档所需内容的几种方法。如果Feed很小,您可以直接使用DOM。这允许您使用XPath count()
函数。
Google Product-Feed基于RSS 2.0或Atom 1.0。 Atom是更好的格式,所以让我们使用它。
// 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非常大,则将其完全加载到内存中可能无法正常工作。但要获得计数,您必须将它们加载到内存中或迭代它们两次。一种可能的方法是文件大小。当然,这不是确切的进展。但应该足够好。
$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会更慢。计算状态也会降低成本。仅显示已读取的条目数可能是更好的主意。
答案 1 :(得分:-1)
使用DOM,您可以统计没有节点。
$dom = new DOMDocument;
$dom->loadXml($xml);
echo $dom->getElementsByTagName('OfferName')->length;