El análisis de XML con PHP

He tenido constantemente un problema con el análisis de XML con PHP y realmente no encontrado «el camino correcto» o al menos de una manera estandarizada de análisis de archivos XML.

En primer lugar estoy tratando de analizar esta:

  <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> 

Estoy usando este código:

$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);
}

Ahora quiero llegar a los «medios de comunicación:contenidos» y los «medios de comunicación:la imagen en miniatura» url atributos, ¿cómo puedo hacer eso? Ahora creo que debería ser el uso de DOMElement::getAttribute pero no he conseguido hacerlo funcionar : /¿alguien Puede arrojar algo de luz sobre esto, y también quisiera saber si esta es una buena forma de analizar XML?

Saludos,
Shadi

  • Todo este asunto/hilo es bastante malo. El problema es la falta de comprensión de los espacios de nombres. Me sugieren que cualquiera que esté leyendo este aprender acerca de los espacios de nombres XML. Personas han mencionado que esta a continuación. El problema es que los medios de comunicación:contenido significa que el ‘contenido’ de la etiqueta que pertenece a los ‘medios de comunicación’ espacio de nombres, no el espacio de nombres predeterminado (que es lo que está consultando en contra).

8 Kommentare

  1. 3

    Puede utilizar SimpleXML según lo sugerido por los otros carteles, pero necesitas utilizar a los niños() y atributos() funciones, para que pueda se ocupan de los diferentes espacios de nombres

    Ejemplo (no probado):

    $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);
        }
    }

    Alternativamente, usted puede usar XPath (de nuevo, no probado):

    $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:[email protected]');
    var_dump($images);
  2. 2

    Probar esta. Que va a funcionar bien.

    $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);
    }
  3. 1

    Esto se me han acabado usando XMLReader:

    <?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 "</pre>";
    
    ?>
  4. 0
    <?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
    }
    
    ?>
    • hmmm, esto realmente no ha funcionado, he intentado colocar la url en lugar de $_POST, pero no obtener el archivo, tengo el archivo en una variable y se la pasó en el simplexmlelement pero todavía no tenía nada dentro de $elemento.
    • Que era en realidad parte de un fragmento de código en mi código. Debo mencionar que usted necesita para cambiar $xml->item en lo que se refiere a la fuente xml que usted está consiguiendo. Me gustaría ver el SimpleXMLElement documentación – pero eso es lo que yo uso para trabajar con XML que puedo enviar desde Adobe Flex
  5. 0

    Trate de usar SimpleXML: http://us2.php.net/simplexml

    • ejecutar los datos a través de simplexml no parece ayudar, que no recoge ninguna de las <medios de comunicación:contenido y <medios de comunicación:la miniatura del contenido, sólo el resto
    • Me sugirió SimpleXML así
  6. 0

    Usted quiere algo como esto:

    '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');

    Creo que va a funcionar, ha sido un tiempo desde que he hecho algo como esto.

    • <rss version=»2.0″ xmlns:creativeCommons=»backend.userland.com/creativeCommonsRssModule» xmlns:media=»search.yahoo.com/mrss«> entonces, ¿cómo implementar eso?!
    • [Lun Jul 13 23:13:04 2009] [error] [cliente de xxx.xxx.xxx.xxx] PHP Fatal error: Llamada a una función miembro getAttribute() en un no-objeto en /v2.php en la línea 73
    • Esta es una buena solución, sólo hay un confuso cosa; la getElementsByTagNameNS generalmente no relacionados a $nodo (que es parte de una iteración), pero que está relacionado con el XML del Documento de la Raíz, el principal objeto DOM. Si la variable de $xml = new DOMDocument();, a continuación, esta es la forma en que va a trabajar: $content = $xml->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'content')->item($i);
  7. 0

    Puede obtener el error Call to a member function getAttribute() on a non-object si un alimento es la falta de entradas como thumbnail, así que, aunque me gusta @Helder Róbalo la respuesta que usted debe comprobar para asegurarse de que existe un nodo antes de intentar usar cosas como 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);
  8. 0

    Medios de comunicación:el contenido de los atributos son en realidad bastante fácil de conseguir con un 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'];
      }
    }

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea