Vamos a ver las diferentes maneras que hay para leer, parsear o recorrer un XML con las funciones de PHP simpleXML. Con dichas funciones accederemos a los diferentes nodos del XML, a los atributos y a los namespaces.
Otras 2 funciones de PHP muy útiles para trabajar con XML y su codificación son:
Espero que no se os haga espeso y largo el post, pero he intentado resumir las operaciones básicas para operar con XMLs.
Son los diferentes tags y niveles con la jerarquía de padres e hijos donde se aloja la info del XML, por ejemplo:
<nodo_padre> <nodo_hijo>valor1</nodo_hijo> <nodo_hijo>valor2</nodo_hijo> </nodo_padre>
En este ejemplo vemos los diferentes valores que hay en los nodos hijos agrupados en un nodo padre.
Los atributos de un xml se encuentran dentro de la declaración de un nodo, por ejemplo:
<nodo_padre> <nodo_hijo atributo="valor atributo">valor1</nodo_hijo> <nodo_hijo atributo="valor 2 atributo">valor2</nodo_hijo> </nodo_padre>
Podéis ver en cada nodo hijo el atributo.
Son prefijos que se declaran en cada nodo del XML, por ejemplo:
<v:vehiculo> <v:marca>valor1</v:marca> <v:modelo>valor2</v:modelo> </v:vehiculo>
Ahí tenemos el namespace ‘v’ que sirve para referenciar vehículos y a su vez su marca y modelo.
Las diferentes funciones de PHP simpleXML que vamos a ver son:
Para realizar este post he extraído información de la web oficial de simpleXML.
La función simplexml_load_file() carga un fichero XML en un objeto, es decir, el XML se carga en una variable. Su sintaxis es la siguiente:
simplexml_load_file( $ruta_xml, $clase, $opciones, $ns, $prefijo);
Os lo explico:
Quizás nunca uséis los parámetros opcionales, ahora os pongo un código de ejemplo básico para la mayoría de los casos:
$carga_xml = simplexml_load_file("/ruta_del_xml/nombre.xml");
La función simplexml_load_string() es similar por no decir idéntica que simplexml_load_file(), esta nueva función carga la estructura XML almacenada en una variable dentro de un objeto.
La sintaxis y parámetros como ya he dicho son idénticos:
simplexml_load_string( $variable_xml, $clase, $opciones, $ns, $prefijo);
Un ejemplo de llamada sería así:
$xml=<<<XML <nodo_padre> <nodo_hijo>valor1</nodo_hijo> <nodo_hijo>valor2</nodo_hijo> </nodo_padre> XML; $carga_xml = simplexml_load_string($xml);
Con los anteriores códigos y ejemplos hemos visto cómo cargar un XML en un objeto, este objeto creado es muy parecido a un array asociativo. He preparado este primer ejemplo con un XML con esta estructura:
<?xml version='1.0' encoding='UTF-8'?> <nodo_padre> <nodo_hijo>valor1</nodo_hijo> <nodo_hijo>valor2</nodo_hijo> </nodo_padre>
El código PHP para acceder a un nodo (primer valor) es el siguiente:
$xml = simplexml_load_file("017-php-simplexml01.xml"); echo $xml->nodo_hijo;
Os explico:
En el primer ejemplo hemos podido acceder al primer valor de un XML, ahora vamos a ver cómo recorrer o parsear todos los nodos de un XML.
En este segundo ejemplo también vamos a acceder a un 3º nivel de nodos para que veáis cómo se accede a nodos interiores. La estructura del XML es la siguiente:
<?xml version='1.0' encoding='UTF-8'?> <nodo_padre> <nodo_hijo> <valor>valor1</valor> </nodo_hijo> <nodo_hijo> <valor>valor2</valor> </nodo_hijo> <nodo_hijo> <valor>valor3</valor> </nodo_hijo> <nodo_hijo> <valor>valor4</valor> </nodo_hijo> </nodo_padre>
El código PHP es el siguiente:
$xml = simplexml_load_file("017-php-simplexml02.xml"); foreach ($xml->nodo_hijo as $nodo) { echo $nodo->valor; }
Y ahora explico el código:
Si queremos acceder a un nodo concreto el código sería el siguiente (por ejemplo al nodo 2):
$xml = simplexml_load_file("017-php-simplexml02.xml"); echo $xml->nodo_hijo[1]->valor;
El índice de los nodos comienza por el número 0, siendo el nodo 2 el índice número 1.
Nuevo ejemplo para obtener de una manera sencilla el número de nodos de un XML. La estructura del XML es la siguiente:
<?xml version='1.0' encoding='UTF-8'?> <nodo_padre> <nodo_hijo> <valor>valor1</valor> </nodo_hijo> <nodo_hijo> <valor>valor2</valor> <valor>valor3</valor> <valor>valor4</valor> </nodo_hijo> </nodo_padre>
Con este código vamos a sacar el número de ‘nodos_hijos’:
$xml = simplexml_load_file("017-php-simplexml03.xml"); echo "El número de nodos con nombre 'nodo_hijo' es: " . count($xml->nodo_hijo); echo "El número de nodos con nombre 'valor' del primer 'nodo_hijo' es: " . count($xml->nodo_hijo->valor); echo "El número de nodos con nombre 'valor' del 2º 'nodo_hijo' es: " . count($xml->nodo_hijo[1]->valor);
Explico el código:
Si necesitamos automatizar el recuento de nodos… He preparado este código para contar el número de nodos ‘valor’ dentro de los nodos ‘nodo_hijo’.
$xml = simplexml_load_file("017-php-simplexml03.xml"); foreach ($xml->nodo_hijo as $nodo) { echo count($nodo->valor). "<br>"; }
Podéis verlo funcionando en la misma url del ejemplo anterior.
Os pongo su sintaxis:
attributes($ns ,$prefijo);
Explico las variables:
Para ver en funcionamiento la función anterior he realizado este nuevo ejemplo con un XML con la siguiente estructura.
<?xml version='1.0' encoding='UTF-8'?> <nodo_padre> <nodo_hijo atributo="valor atributo 1" atributo2="valor atributo 2 del nodo 1">nodo1</nodo_hijo> <nodo_hijo atributo="valor atributo 2" atributo2="valor atributo 2 del nodo 2">nodo2</nodo_hijo> <nodo_hijo atributo="valor atributo 3" atributo2="valor atributo 2 del nod 3">nodo3</nodo_hijo> </nodo_padre>
El código PHP sería el siguiente:
$xml = simplexml_load_file("017-php-simplexml04.xml"); foreach ($xml->nodo_hijo as $nodo) { $atributos = $nodo->attributes(); echo "Valor atributo 1--> " .$atributos['atributo']. ", valor atributo 2--> " .$atributos['atributo2']. "<br>"; }
La explicación es sencilla:
Os muestro la sintaxis:
getNameSpaces($recursivo);
El único parámetro a pasar el $recursivo. Si el valor es ‘TRUE‘ devuelve los namespaces del nodo actual y sus nodos hijos, en caso de ser ‘FALSE’ devuelve los namespaces declarados en la raíz del XML. Por defecto el valor es ‘FALSE’.
Nueva código de ejemplo para sacar los namespaces de un XML con la siguiente estructura:
<nodos> <item> <title>Título 1</title> <link>Enlace 1</link> <description>Descripcion 1</description> <media:thumbnail>Thumbnail 1</media:thumbnail> </item> <title>Título 2</title> <link>Enlace 2</link> <description>Descripcion 2</description> <media:thumbnail>Thumbnail 2</media:thumbnail> </item> </nodos>
El código PHP sería el siguiente:
$xml = simplexml_load_file("017-php-simplexml05.xml"); foreach ($xml->nodos->item as $elemento) { echo "El título es" .$elemento->title. "<br>"; echo "El link es" .$elemento->description. "<br>"; echo "El description es" .$elemento->description. "<br>"; //saco los namespaces $namespaces = $elemento->getNameSpaces(true); $media = $elemento->children($namespaces['media']); echo "El thumbnail es:" .$media->thumbnail."<br>"; }
La explicación es sencilla:
Con xpath() podemos acceder a los nodos de otra manera diferente a las vistas anteriormente, su sintaxis es:
xpath($path);
En el parámetro $path pondremos el nodo del XML al que queremos acceder.
Os pongo otro nuevo ejemplo con un XML con la siguiente estructura:
<?xml version='1.0' encoding='UTF-8'?> <nodo_padre> <nodo_hijo>valor1</nodo_hijo> </nodo_padre>
Y el código PHP es:
$xml = simplexml_load_file("017-php-simplexml06.xml"); $valor = $xml->xpath("nodo_hijo"); var_dump($valor);