Разбор XML с использованием PHP - PullRequest
2 голосов
/ 14 июля 2009

У меня постоянно возникала проблема с синтаксическим анализом XML с помощью PHP, и я не нашел «правильный путь» или хотя бы стандартизированный способ синтаксического анализа XML-файлов.

Во-первых, я пытаюсь разобрать это:

  <item> 
     <title>2884400</title> 
     <description><![CDATA[ ><img width="126" alt="" src="http://userserve-ak.last.fm/serve/126/27319921.jpg" /> ]]></description> 
     <link>http://www.last.fm/music/+noredirect/Beatles/+images/27319921</link> 
     <author>anne710</author> 
     <pubDate>Tue, 21 Apr 2009 16:12:31 +0000</pubDate> 
     <guid>http://www.last.fm/music/+noredirect/Beatles/+images/27319921</guid> 
     <media:content url="http://userserve-ak.last.fm/serve/_/27319921/Beatles+2884400.jpg" fileSize="13065" type="image/jpeg" expression="full"  width="126" height="126" /> 
     <media:thumbnail url="http://userserve-ak.last.fm/serve/126/27319921.jpg" type="image/jpeg" width="126" height="126" /> 
  </item> 

Я использую этот код:

$doc = new DOMDocument();
$doc->load('http://ws.audioscrobbler.com/2.0/artist/beatles/images.rss');
$arrFeeds = array();
foreach ($doc->getElementsByTagName('item') as $node) {
    $itemRSS = array ( 
        'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
        'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
        'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
        'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue
        );
    array_push($arrFeeds, $itemRSS);
}

Теперь я хочу получить атрибуты url "media: content" и "media: thumbnail", как мне это сделать? Теперь я думаю, что должен использовать DOMElement :: getAttribute, но мне не удалось заставить его работать: / Может кто-нибудь пролить свет на это, а также сообщить мне, если это хороший способ для анализа XML?

С уважением, Шади

Ответы [ 8 ]

3 голосов
/ 14 июля 2009

Вы можете использовать SimpleXML , как предложено другими авторами, но вам нужно использовать функции children () и attribute (), чтобы вы могли иметь дело с различными пространствами имен

Пример (не проверено):

$feed = file_get_contents('http://ws.audioscrobbler.com/2.0/artist/beatles/images.rss');
$xml = new SimpleXMLElement($feed);
foreach ($xml->channel->item as $item) {
    foreach ($item->children('http://search.yahoo.com/mrss' as $media_element) {
        var_dump($media_element);
    }
}

Кроме того, вы можете использовать XPath (опять же, не проверено):

$feed = file_get_contents('http://ws.audioscrobbler.com/2.0/artist/beatles/images.rss');
$xml = new SimpleXMLElement($feed);
$xml->registerXPathNamespace('media', 'http://ws.audioscrobbler.com/2.0/artist/beatles/images.rss');
$images = $xml->xpath('/rss/channel/item/media:content@url');
var_dump($images);
2 голосов
/ 21 января 2010

Попробуй это. Это будет хорошо работать.

$doc = new DOMDocument();
$doc->load('http://ws.audioscrobbler.com/2.0/artist/beatles/images.rss');
$arrFeeds = array();
foreach ($doc->getElementsByTagName('item') as $node) {
    $itemRSS = array ( 
        'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
        'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
        'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
        'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue,
        'thumbnail' => $node->getElementsByTagName('thumbnail')->item(0)->getAttribute('url')
    );
    array_push($arrFeeds, $itemRSS);
}
1 голос
/ 14 июля 2009

Так я и сделал, используя XMLReader:

<code><?php

define ('XMLFILE', 'http://ws.audioscrobbler.com/2.0/artist/vasco%20rossi/images.rss');
echo "<pre>";

$items = array ();
$i = 0;

$xmlReader = new XMLReader();
$xmlReader->open(XMLFILE, null, LIBXML_NOBLANKS);

$isParserActive = false;
$simpleNodeTypes = array ("title", "description", "media:title", "link", "author", "pubDate", "guid");

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"),
                "type" => $xmlReader->getAttribute("type")
        );
    } else if ($name == "media:content") {
        $items[$i]['media:content'] = array (
                "url" => $xmlReader->getAttribute("url"),
                "width" => $xmlReader->getAttribute("width"),
                "height" => $xmlReader->getAttribute("height"),
                "filesize" => $xmlReader->getAttribute("fileSize"),
                "expression" => $xmlReader->getAttribute("expression")
        );
    }
}

print_r($items);
echo "
"; ?>
0 голосов
/ 08 ноября 2013

Медиа: на самом деле довольно просто получить атрибуты содержимого с помощью SIMPLE XML

if(!@$x=simplexml_load_file($feed_url)){

}
else
{
  foreach($x->channel->item as $entry)
  {
    $media = $entry->children('http://search.yahoo.com/mrss/')->attributes();
    $url = (string) $media['url'];
  }
}
0 голосов
/ 13 июля 2013

Вы можете получить ошибку Call to a member function getAttribute() on a non-object, если в ленте отсутствуют записи, такие как thumbnail, поэтому, хотя мне нравится ответ @Helder Robalo, вы должны убедиться, что узел существует, прежде чем пытаться использовать такие вещи, как getAttribute():

<?php

header('Content-type: text/plain; charset=utf-8');

$doc = new DOMDocument();
$doc->load('http://ws.audioscrobbler.com/2.0/artist/beatles/images.rss');
$arrFeeds = array();
foreach ($doc->getElementsByTagName('item') as $node) {
    $itemRSS = array (
        'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
        'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
        'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
        'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue
    );

    if( sizeof($node->getElementsByTagName('thumbnail')->item(0)) > 0 )
    {
        $itemRSS['thumbnail'] = $node->getElementsByTagName('thumbnail')->item(0)->getAttribute('url');
    }
    else
    {
        $itemRSS['thumbnail'] = '';
    }

    array_push($arrFeeds, $itemRSS);
}


print_r($arrFeeds);
0 голосов
/ 14 июля 2009

Попробуйте использовать SimpleXML: http://us2.php.net/simplexml

0 голосов
/ 14 июля 2009
<?php

#Convert the String Into XML
$xml = new SimpleXMLElement($_POST['name']);

#Itterate through the XML for the data 

$values = "VALUES('' , ";
foreach($xml->item as $item)
{
 //you now have access to that aitem
}

?>
0 голосов
/ 14 июля 2009

Вы бы хотели что-то вроде этого:

'content' => $node->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'content')->item(0)->getAttribute('url');
'thumbnail' => $node->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'thumbnail')->item(0)->getAttribute('url');

Я верю, что это сработает, давно я не делал ничего подобного.

...