9 - Recuperando datos mediante la propiedad responseXML del objeto XMLHttpRequest


La propiedad responseXML a diferencia de la propiedad responseText recupera los datos como XML y debemos recorrerlo mediante las funciones del DOM.

Es necesario que el programa que se ejecute en el servidor estructure los datos en formato XML.

Para probar el funcionamiento de esta propiedad del objeto XMLHttpRequest implementaremos una página que muestre en un control select los nombres de una serie de paises. Cuando se seleccione uno y se presione un botón recuperaremos de dicho país el nombre de la capital, su superficie, cantidad de habitantes y su idioma.

El servidor generará un archivo con formato XML y lo retornará al cliente.

El primer archivo (pagina1.html):

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Problema</title>
  <script src="funciones.js"></script>
</head>
<body>
  <h1>Datos de paises.</h1>
  Seleccione el pais
  <select id="pais">
  <option value="0" selected>seleccione</option>
  <option value="Argentina">Argentina</option>
  <option value="Brasil">Brasil</option>
  <option value="Chile">Chile</option>
  </select><br>
  <input type="button" id="boton1" value="Recuperar">
  <div id="resultados"></div>
</body>
</html>

Este archivo HTML no tiene nada nuevo.

El archivo que contiene las funciones JavaScript (funciones.js):

addEventListener('load',inicializarEventos,false);

function inicializarEventos()
{
  var ob=document.getElementById('boton1');
  ob.addEventListener('click',presionBoton,false);
}

function presionBoton(e)
{
  var ob1=document.getElementById('pais');
  recuperarDatos(ob1.value);
}

var conexion1;
function recuperarDatos(pais) 
{
  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventos;
  conexion1.open('GET','pagina1.php?pa='+pais, true);
  conexion1.send();
}

function procesarEventos()
{
  var resultados = document.getElementById("resultados");

  if(conexion1.readyState == 4)
  {
    var xml = conexion1.responseXML;
    var capital=xml.getElementsByTagName('capital');
    var superficie=xml.getElementsByTagName('superficie');
    var idioma=xml.getElementsByTagName('idioma');
    var poblacion=xml.getElementsByTagName('poblacion');
    resultados.innerHTML='Capital='+capital[0].firstChild.nodeValue + '<br>' +
                         'Superficie='+superficie[0].firstChild.nodeValue + '<br>' +
                         'Idioma='+idioma[0].firstChild.nodeValue + '<br>' +
                         'Poblacion='+poblacion[0].firstChild.nodeValue ;
  } 
  else 
  {
    resultados.innerHTML = 'Cargando...';
  }
}

En la primer función que se ejecuta enlazamos la función a ejecutar al presionar el botón:

function inicializarEventos()
{
  var ob=document.getElementById('boton1');
  ob.addEventListener('click',presionBoton,false);
}

Cuando se presiona el botón se ejecuta la función presionBoton:

function presionBoton(e)
{
  var ob1=document.getElementById('pais');
  recuperarDatos(ob1.value);
}

Recuperamos el pais seleccionado en el control select y llamamos a la función recuperarDatos pasando como parámetro dicho pais.

La función recuperarDatos crea un objeto de la clase XMLHttpRequest y abre una conexión con el servidor mediante el método GET pasando como parámetro el nombre del país seleccionado:

function recuperarDatos(pais) 
{
  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventos;
  conexion1.open('GET','pagina1.php?pa='+pais, true);
  conexion1.send();
}

Como sabemos la propiedad onreadystatechange se inicializa con el nombre de la función que procesará los cambios de estado del objeto XMLHttpRequest. En este caso el algoritmo de la función es:

function procesarEventos()
{
  var resultados = document.getElementById("resultados");

  if(conexion1.readyState == 4)
  {
    var xml = conexion1.responseXML;
    var capital=xml.getElementsByTagName('capital');
    var superficie=xml.getElementsByTagName('superficie');
    var idioma=xml.getElementsByTagName('idioma');
    var poblacion=xml.getElementsByTagName('poblacion');
    resultados.innerHTML='Capital='+capital[0].firstChild.nodeValue + '<br>' +
                         'Superficie='+superficie[0].firstChild.nodeValue + '<br>' +
                         'Idioma='+idioma[0].firstChild.nodeValue + '<br>' +
                         'Poblacion='+poblacion[0].firstChild.nodeValue ;                       
  } 
  else 
  {
    resultados.innerHTML = 'Cargando...';
  }
}

Cuando los datos han llegado completamente, es decir la propiedad readyState del objeto XMLHttpRequest almacena el valor 4 procedemos a cargar los datos dentro del div 'resultados'.

Primero almacenamos la información en la variable xml:

    var xml = conexion1.responseXML;

Ahora podemos recorrer el archivo XML mediante las funciones que provee el DOM.

    var capital=xml.getElementsByTagName('capital');

Esta línea genera un vector con las referencias a todos los elementos llamados 'capital' (En nuestro caso hay uno solo)

Como se trata de un vector luego debemos accederlo por medio de un subíndice (indicamos el valor cero ya que contiene solo un elemento):

capital[0].firstChild.nodeValue

Como sabemos el texto contenido entre las marcas se trata de otro nodo y lo podemos acceder mediante el método firstChild. Por último para acceder a la información de dicho nodo de texto lo hacemos mediante la propiedad nodeValue (Tener en cuenta que todos estos conceptos se ven detenidamente en el tutorial de DHTML)


El último archivo que integra este problema es el que se ejecuta en el servidor (pagina1.php):

<?php
if ($_REQUEST['pa']=='Argentina')
{
  $superficie=2700000;
  $capital="Buenos Aires";
  $idioma="Castellano";
  $poblacion=38000000;
}
if ($_REQUEST['pa']=='Brasil')
{
  $superficie=8500000;
  $capital="Brasilia";
  $idioma="Portugues";
  $poblacion=163000000;
}
if ($_REQUEST['pa']=='Chile')
{
  $superficie=750000;
  $capital="Santiago";
  $idioma="Castellano";
  $poblacion=15000000;
}

$xml="<?xml version=\"1.0\"?>\n";
$xml.="<pais>\n";
$xml.="<superficie>$superficie</superficie>\n";
$xml.="<capital>$capital</capital>\n";
$xml.="<idioma>$idioma</idioma>\n";
$xml.="<poblacion>$poblacion</poblacion>\n";
$xml.="</pais>\n";
header('Content-Type: text/xml');
echo $xml;

?>

Nuevamente para simplificar el problema no hemos almacenado los datos de los paises en una base de datos. Mediante una serie de if verificamos de que pais se trata e inicializamos cuatro variables.

Por último creamos un string organizando la información con formato XML.

Mediante la función header informamos al navegador que se trata de un archivo XML.

Finalmente procedemos a imprimir la variable $xml luego de enviar la cabecera al navegador.



Problema resuelto.


Implementar una página que muestre en un control select los nombres de una serie de paises. Cuando se seleccione uno y se presione un botón recuperaremos de dicho pais el nombre de la capital, su superficie, cantidad de habitantes y su idioma.


pagina1.html



Ejecutar ejemplo



funciones.js




pagina1.php


Problema propuesto.

Modificar el problema resuelto de tal manera que no requiera un botón para actualizar los datos del pais. Se deben recuperar los datos inmediatamente seleccionado un item del control select.


Ver solución



pagina.html

<!DOCTYPE html> <html> <head> <title>Problema</title> <meta charset="utf-8"> <script src="funciones.js"></script> </head> <body> <h1>Datos de paises.</h1> <p>Seleccione el pais <select id="pais"> <option value="0" selected>seleccione</option> <option value="Argentina">Argentina</option> <option value="Brasil">Brasil</option> <option value="Chile">Chile</option> </select> </p> <div id="resultados"></div> </body> </html>

funciones.js

addEventListener('load',inicializarEventos,false); function inicializarEventos() { var ob=document.getElementById('pais'); ob.addEventListener('change',cambioEnSelect,false); } function cambioEnSelect(e) { var ob1=document.getElementById('pais'); recuperarDatos(ob1.value); } var conexion1; function recuperarDatos(pais) { conexion1=new XMLHttpRequest(); conexion1.onreadystatechange = procesarEventos; conexion1.open('GET','pagina1.php?pa='+pais, true); conexion1.send(); } function procesarEventos() { var resultados = document.getElementById("resultados"); if(conexion1.readyState == 4) { var xml = conexion1.responseXML; var capital=xml.getElementsByTagName('capital'); var superficie=xml.getElementsByTagName('superficie'); var idioma=xml.getElementsByTagName('idioma'); var poblacion=xml.getElementsByTagName('poblacion'); resultados.innerHTML='Capital='+capital[0].firstChild.nodeValue + '<br>' + 'Superficie='+superficie[0].firstChild.nodeValue + '<br>' + 'Idioma='+idioma[0].firstChild.nodeValue + '<br>' + 'Poblacion='+poblacion[0].firstChild.nodeValue ; } else { resultados.innerHTML = 'Cargando...'; } }

pagina1.php

<?php if ($_REQUEST['pa']=='Argentina') { $superficie=2700000; $capital="Buenos Aires"; $idioma="Castellano"; $poblacion=38000000; } if ($_REQUEST['pa']=='Brasil') { $superficie=8500000; $capital="Brasilia"; $idioma="Portugues"; $poblacion=163000000; } if ($_REQUEST['pa']=='Chile') { $superficie=750000; $capital="Santiago"; $idioma="Castellano"; $poblacion=15000000; } $xml="<?xml version=\"1.0\"?>\n"; $xml.="<pais>\n"; $xml.="<superficie>$superficie</superficie>\n"; $xml.="<capital>$capital</capital>\n"; $xml.="<idioma>$idioma</idioma>\n"; $xml.="<poblacion>$poblacion</poblacion>\n"; $xml.="</pais>\n"; header('Content-Type: text/xml'); echo $xml; ?>
  Ejecutar ejemplo	

Retornar