кстианский,
Если вы беспокоитесь об использовании памяти, я бы рекомендовал держаться подальше от DOM / XPath, так как он требует, чтобы весь файл был сначала прочитан в память. XMLReader читает только по частям за раз (вероятно, 8 КБ, так как это кажется стандартным размером фрагмента PHP).
Я переписал то, что вы изначально опубликовали, и он фиксирует следующие элементы, содержащиеся в элементе <item>
:
title
description
media:thumbnail
media:title
Следует помнить, что XMLReader::localName
будет возвращать имя элемента минус любое объявление XMLNS (например, media:thumbnail
localName
равно thumbnail
). Вы должны быть осторожны с этим, так как значение media:title
может перезаписать значение title
.
Вот что я переписал:
<code><?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 "
";
?>
Если у вас есть какие-либо вопросы о том, как это работает, я был бы более чем рад ответить на них для вас.