<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/"> <channel> <title>Title of RSS feed</title> <link>http://www.google.com</link> <description>Details about the feed</description> <pubDate>Mon, 24 Nov 08 21:44:21 -0500</pubDate> <language>en</language> <item> <title>Article 1</title> <description><![CDATA[How to use StackOverflow.com]]></description> <link>http://youtube.com/?v=y6_-cLWwEU0</link> <media:player url="http://youtube.com/?v=y6_-cLWwEU0" /> <media:thumbnail url="http://img.youtube.com/vi/y6_-cLWwEU0/default.jpg" width="120" height="90" /> <media:title>Jared on StackOverflow</media:title> <media:category label="Tags">tag1,tag2</media:category> <media:credit>Jared</media:credit> <enclosure url="http://youtube.com/v/y6_-cLWwEU0.swf" length="233" type="application/x-shockwave-flash"/> </item> </channel> </rss>
Я решил использовать XMLReader для разбора больших файлов xml. У меня возникли проблемы с получением данных внутри каждого элемента, особенно миниатюры
Вот мой код
////////////////////////////// $itemList = array(); $i=0; $xmlReader = new XMLReader(); $xmlReader->open('XMLFILE'); while($xmlReader->read()) { if($xmlReader->nodeType == XMLReader::ELEMENT) { if($xmlReader->localName == 'title') { $xmlReader->read(); $itemList[$i]['title'] = $xmlReader->value; } if($xmlReader->localName == 'description') { // move to its textnode / child $xmlReader->read(); $itemList[$i]['description'] = $xmlReader->value; } if($xmlReader->localName == 'media:thumbnail') { // move to its textnode / child $xmlReader->read(); $itemList[$i]['media:thumbnail'] = $xmlReader->value; $i++; } } } ////////////////
Целесообразно использовать DOMXpath, поскольку я разбирал огромный XML-файл? Я очень ценю ваш совет.
кстианской,
Если использование памяти связано с вашей проблемой, я бы рекомендовал держаться подальше от DOM / XPath, поскольку для этого сначала необходимо прочитать весь файл в памяти. XMLReader читает только фрагмент за один раз (вероятно, 8K, как кажется, стандартный размер PHP Chunk).
Я переписал то, что вы изначально разместили, и он фиксирует следующие элементы, содержащиеся в <item>
:
title
description
media:thumbnail
media:title
Вы должны помнить, что XMLReader::localName
вернет имя элемента минус любое объявление XMLNS (например, имя файла media:thumbnail
thumbnail
). Вы захотите быть осторожным в этом, так как значение media:title
может перезаписать значение title
.
Вот что я переписал:
<?php define ('XMLFILE', dirname(__FILE__) . '/Rss.xml'); echo "<pre>"; $items = array (); $i = 0; $xmlReader = new XMLReader(); $xmlReader->open (XMLFILE, null, LIBXML_NOBLANKS); $isParserActive = false; $simpleNodeTypes = array ("title", "description", "media:title"); while ($xmlReader->read ()) { $nodeType = $xmlReader->nodeType; // Only deal with Beginning/Ending Tags if ($nodeType != XMLReader::ELEMENT && $nodeType != XMLReader::END_ELEMENT) { continue; } else if ($xmlReader->name == "item") { if (($nodeType == XMLReader::END_ELEMENT) && $isParserActive) { $i++; } $isParserActive = ($nodeType != XMLReader::END_ELEMENT); } if (!$isParserActive || $nodeType == XMLReader::END_ELEMENT) { continue; } $name = $xmlReader->name; if (in_array ($name, $simpleNodeTypes)) { // Skip to the text node $xmlReader->read (); $items[$i][$name] = $xmlReader->value; } else if ($name == "media:thumbnail") { $items[$i]['media:thumbnail'] = array ( "url" => $xmlReader->getAttribute("url"), "width" => $xmlReader->getAttribute("width"), "height" => $xmlReader->getAttribute("height") ); } } var_dump ($items); echo "</pre>"; ?>
Если у вас есть какие-либо вопросы о том, как это работает, я был бы более чем счастлив ответить на них за вас.