Foros del Web » Programando para Internet » Javascript »

No carga el XML

Estas en el tema de No carga el XML en el foro de Javascript en Foros del Web. Hola y Feliz nuevo año para todos los foreros de javascript. Aquí vengo con mi primera candanga del año. Resulta que tengo este XML Menu.xml ...
  #1 (permalink)  
Antiguo 01/01/2012, 12:15
Avatar de jorgelpadronb  
Fecha de Ingreso: agosto-2011
Ubicación: Cuba
Mensajes: 281
Antigüedad: 12 años, 8 meses
Puntos: 37
No carga el XML

Hola y Feliz nuevo año para todos los foreros de javascript. Aquí vengo con mi primera candanga del año. Resulta que tengo este XML

Menu.xml
Código XML:
Ver original
  1. <?xml version="1.0" encoding="iso-8859-1"?>
  2. <Menu>
  3.     <Item Id=1 Text="Element1" Link="" Title="Element1" Inside=0></Item>
  4.     <Item Id=2 Text="Element2" Link="" Title="Element2" Inside=0></Item>
  5.     <Item Id=3 Text="Element3" Link="" Title="Element3" Inside=1></Item>
  6.     <Item Id=4 Text="Element4" Link="" Title="Element4" Inside=1></Item>
  7.     <Item Id=5 Text="Element5" Link="Element5" Title="Element5" Inside=2></Item>
  8.     <Item Id=6 Text="Element6" Link="Element6" Title="Element6" Inside=2></Item>
  9.     <Item Id=7 Text="Element7" Link="Element7" Title="Element7" Inside=3></Item>
  10.     <Item Id=8 Text="Element8" Link="Element8" Title="Element8" Inside=3></Item>
  11.     <Item Id=9 Text="Element9" Link="Element9" Title="Element9" Inside=4></Item>
  12.     <Item Id=10 Text="Element10" Link="Element10" Title="Element10" Inside=4></Item>
  13. </Menu>

Y este código para cargarlo:

Código Javascript:
Ver original
  1. if (window.XMLHttpRequest){
  2.          xmlDoc = new window.XMLHttpRequest();
  3.          xmlDoc.open("GET", 'Menu.xml', false);
  4.          xmlDoc.send("");
  5.          xmlResult = xmlDoc.responseXML;
  6.      }else if (ActiveXObject("Microsoft.XMLDOM")){
  7.          xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
  8.          xmlDoc.async = false;
  9.          xmlDoc.load('Menu.xml');
  10.          xmlResult = xmlDoc;
  11.      }
  12.      alert(xmlResult);

Entonces, por qué alert(xmlResult) me da NULL y no me carga los datos del XML?

Si alguien me puede tirar un cabito se lo agradezco.

Saludos
__________________
Los hombres pequeños, nunca se sienten pequeños; los hombres grandes, nunca se sienten grandes.

No sé quien fué el que dijo eso, pero está bueno.
  #2 (permalink)  
Antiguo 01/01/2012, 16:31
Avatar de jorgelpadronb  
Fecha de Ingreso: agosto-2011
Ubicación: Cuba
Mensajes: 281
Antigüedad: 12 años, 8 meses
Puntos: 37
Respuesta: No carga el XML

Hola. Creo que ya solucioné esa parte. De esta forma:

Código Javascript:
Ver original
  1. if (navigator.appName == "Microsoft Internet Explorer"){
  2.         var xmlResult = new ActiveXObject("Microsoft.XmlDom");
  3.         xmlResult.load("Menu.xml");
  4.      }else{          
  5.         var xmlResult = document.implementation.createDocument("GET","Menu.xml",false);
  6.      }

Ahora el alert(xmlResult) me dice [object.Document] y cuando hago:

xmlList = xmlResult.getElementsByTagName('Item');

El alert(xmlList) me da [object.NodeList], pero cuando hago:

var count = xmlList.length;

El alert(count) me da 0. No entiendo si tengo 10 tags <Item> en el xml, por qué no me los lista?

Saludos.
__________________
Los hombres pequeños, nunca se sienten pequeños; los hombres grandes, nunca se sienten grandes.

No sé quien fué el que dijo eso, pero está bueno.
  #3 (permalink)  
Antiguo 01/01/2012, 21:55
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: No carga el XML

buenas,
el tema del XHR no veo por que te produce problema. desde iexplorer7, XMLHttpRequest es compatible por lo que no tendrias que usar la version activex. pero no importa, ya lo tienes solucionado. respecto a los elementos <item>, debes tener en claro que, a diferencia de html, xml es sensible a las minusculas/mayusculas. por tanto, <item> no es lo mismo que <Item> ni <ItEm> o alguna otra variante.

__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #4 (permalink)  
Antiguo 02/01/2012, 23:52
Avatar de jorgelpadronb  
Fecha de Ingreso: agosto-2011
Ubicación: Cuba
Mensajes: 281
Antigüedad: 12 años, 8 meses
Puntos: 37
Respuesta: No carga el XML

Cita:
Iniciado por zerokilled Ver Mensaje
buenas,
el tema del XHR no veo por que te produce problema. desde iexplorer7, XMLHttpRequest es compatible por lo que no tendrias que usar la version activex. pero no importa, ya lo tienes solucionado. respecto a los elementos <item>, debes tener en claro que, a diferencia de html, xml es sensible a las minusculas/mayusculas. por tanto, <item> no es lo mismo que <Item> ni <ItEm> o alguna otra variante.

Hola zerokilled. Gracias por responder. Lo que me dices de las mayúsculas no lo había considerado, pero igual no es eso, porque me he fijado y tengo todos los Item con I mayúscula, tanto en el javascript como en el xml.

Lo que me pregunto es si el procedimiento que estoy utilizando es correcto o tiene algún error. Es correcto eso que hago de acceder a los items con getElementsByTagName o se requiere algo diferente para extraer los Items del xml. He leido algo sobre Nodos y esas cosas pero la verdad no entiendo mucho de como funciona.

Saludos.
__________________
Los hombres pequeños, nunca se sienten pequeños; los hombres grandes, nunca se sienten grandes.

No sé quien fué el que dijo eso, pero está bueno.
  #5 (permalink)  
Antiguo 03/01/2012, 00:19
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: No carga el XML

me falla la vista o no se en que estaba pensando. juro haber visto diferencia en la i. es de mi parecer que tanto el activex como createDocument devuelve un objeto tipo document. si eso esta bien, entonces debe funcionarte getElementsByTagName. acerca de la forma correcta, dependera de como tu quieras trabajar. para efecto de tu proposito, creo que es mas comodo con getElementsByTagName. lo que debes velar es cuando intentas obtener los elementos. recuerda que debes esperar a que el documento cargue completamente ya que dichas instrucciones son asincronos.
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #6 (permalink)  
Antiguo 03/01/2012, 02:17
Avatar de jorgelpadronb  
Fecha de Ingreso: agosto-2011
Ubicación: Cuba
Mensajes: 281
Antigüedad: 12 años, 8 meses
Puntos: 37
Respuesta: No carga el XML

Cita:
Iniciado por zerokilled Ver Mensaje
me falla la vista o no se en que estaba pensando. juro haber visto diferencia en la i. es de mi parecer que tanto el activex como createDocument devuelve un objeto tipo document. si eso esta bien, entonces debe funcionarte getElementsByTagName. acerca de la forma correcta, dependera de como tu quieras trabajar. para efecto de tu proposito, creo que es mas comodo con getElementsByTagName. lo que debes velar es cuando intentas obtener los elementos. recuerda que debes esperar a que el documento cargue completamente ya que dichas instrucciones son asincronos.
Parece que es el color de la fuente que tiende a confundir, en un momento a mí también me pareció que la i era minúscula, pero me fijé bién y es mayúscula. También lo comprobé en el código que tengo aquí y efectivamente todas son mayúsculas.

Es probable que sea que no estoy dando tiempo a que cargue el xml? Yo tengo una función para cargar el xml, y en esa misma función, justo después de las instrucciones para cargar hago getElementsByTagName para extraer los los Items a un Array. Es posible que no me extraiga nada porque no estoy dando tiempo a que el xml cargue completo? Puede pasar eso aunque el xml tenga solo 10 elementos? En ese caso que puedo hacer para asegurar que el xml ha cargado completo antes de hacer getElementsByTagName dentro de la misma función que carga el xml?

Esta es la función completa:

Código Javascript:
Ver original
  1. function LoadItems(){
  2.      //aquí declaro las variables que voy a usar
  3.      //las que no están declaradas es porque son globales y se declaran fuera de la función
  4.      var xmlFile = 'Menu.xml';//nombre del archivo XML
  5.      var itemMask = {Id: 0,
  6.                      Text: '',
  7.                      Link: '',
  8.                      Title: '',
  9.                      Inside: 0}//Objeto para modelo para recoger los datos del XML
  10.      var xmlResult = null;//Variable para almacenar el documento XML cargado
  11.      var xmlList = null;//Variable para la lista de Items leidos del XML
  12.      var count = 0;//Variable para la cantidad de Items
  13.      //Ahora cargo el XML para diferentes navegadores
  14.      if (navigator.appName == "Microsoft Internet Explorer"){
  15.         xmlResult = new ActiveXObject("Microsoft.XMLDOM");
  16.         xmlResult.async = false;
  17.         xmlResult.load(xmlFile);
  18.      }else{          
  19.         var xmlResult = document.implementation.createDocument("GET",xmlFile,false);
  20.      }
  21.      //Una vez cargado...
  22.      alert(xmlResult);//Esto me da [object.document]
  23.      xmlList = xmlResult.getElementsByTagName('Item');//Cargo los Items del documento
  24.      alert(xmlList);//Esto me da [object.NodeList]
  25.      Menu = new Array();//Sobreescribo la variable global Menu con un Array vacio
  26.      var i = 0;//Inicializo el contador para el bucle
  27.      var count = xmlList.length;//Tomo la cantidad de Items para el bucle
  28.      alert(count);//Ahora es el problema, me pone 0
  29.      for(i=0;i<count;i++){
  30.         itm = xmlList[i];
  31.         itemMask['Id'] = itm.Id;
  32.         itemMask['Text'] = itm.Text;
  33.         itemMask['Link'] = itm.Link;
  34.         itemMask['Title'] = itm.Title;
  35.         itemMask['Inside'] = itm.Inside;
  36.         Menu[i] = itemMask;
  37.      }//Y luego por supuesto el bucle no se ejecuta porque la variable count es 0
  38.  }

Datos importantes: Estoy usando Google Chrome.

Saludos.
__________________
Los hombres pequeños, nunca se sienten pequeños; los hombres grandes, nunca se sienten grandes.

No sé quien fué el que dijo eso, pero está bueno.

Última edición por jorgelpadronb; 03/01/2012 a las 02:45
  #7 (permalink)  
Antiguo 03/01/2012, 05:44
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: No carga el XML

no he leido detenidamente todo el código, fui directamente a la parte de DOMImplementation (document.implementation). del activex no voy hacer mención porque no he buscado información sobre su implementación. los argumentos de createDocument son: namespaceURI, qualifiedName, y el DocumentType. básicamente namespaceURI es la misma función del atributo xmlns, qualifiedName es el elemento raíz del documento, y DocumentType es la misma función que la declaración <!DOCTYPE> de un documento (si, xml también puede tener DOCTYPE). (w3.org#Core DOM Level 2.) fíjate que de plano estas usando mal la función. por otro lado, no tengo claro si la función load y la propiedad async es parte del estandar. resulta que firefox tiene soporte para ello, por el contrario webkit (chrome) no lo reconoce.

supongo que querás darle soporte a varios navegadores porque de lo contrario no tendrías la versión activex. mi recomendación es volver con XMLHttpRequest. para mis gusto, es menos complicado y funciona desde la versión iexplorer7, por lo que no tendrías que complicarte con el uso de activex. probablemente el error que estabas teniendo inicialmente es el mismo que antes mencione, no esperabas a que terminará de cargar el documento. tienes dos formas de hacerlo: asíncrono con evento o síncrono. la diferencia es que en asíncrono el navegador no se detiene a esperar la respuesta de la petición, por tanto el flujo continua de forma normal. en síncrono, el navegador se "congela" hasta que este reciba alguna respuesta de la petición y luego continua con el proceso. el modo a seleccionar es de tu gusto o necesidad. simplemente tienes que hacer lo siguiente.
Código:
// versión async;
var request = new XMLHttpRequest();
request.onreadystatechange = function(){
// cuando el estado llegue a la fase "complete", invocas el resto del código que maneja el documento xml;
};
request.open(method, url, true); // true significa que la petición es asíncrona;
request.send();


// versión síncrona;
var request = new XMLHttpRequest();
request.open(method, url, false); // false significa que la petición es síncrona;
request.send();
// resto del código que maneja el documento xml;
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #8 (permalink)  
Antiguo 03/01/2012, 09:48
Avatar de Tecna  
Fecha de Ingreso: enero-2010
Mensajes: 291
Antigüedad: 14 años, 3 meses
Puntos: 45
Respuesta: No carga el XML

Buenas,

como ya te dijo Zerokilled los argumentos que estás pasando a createDocument están mal y además, no parece que incluyas la respuesta ajax en el nuevo documento en ningún sitio, que si los datos están en xml lo lógico sería usar responseXML. Aunque es preferible no cargar los datos de forma dinámica por accesibilidad.

En principio aunque createDocument es unicamente para xml, yo lo he usado para crear documentos html y funciona en todos los navegadores "decentes", aunque alguno como chrome tenía sus particularidades. Con este truco podemos tratar los datos en el servidor y generar páginas estáticas de puro html que estarán siempre disponibles y que serán las que carguemos mediante la petición ajax, en el nuevo documento creado con createDocument pudiendo acceder al árbol del documento y a cualquiera de sus elementos mediante el DOM para seleccionar la información que necesitemos de forma rápida.
  #9 (permalink)  
Antiguo 04/01/2012, 01:32
Avatar de jorgelpadronb  
Fecha de Ingreso: agosto-2011
Ubicación: Cuba
Mensajes: 281
Antigüedad: 12 años, 8 meses
Puntos: 37
Respuesta: No carga el XML

Hola amigos. Muchas gracias por sus respuestas. Gracias a ustedes ya comienzo a ver las cosas mas claras. Me he decidido por la vía sincrona, pues al ser un XML pequeño la "conjelación" en la ejecución es inperceptible. Probé esto:

Código Javascript:
Ver original
  1. var xmlRequest = new XMLHttpRequest();
  2. xmlRequest.open('GET', 'Menu.xml', false);
  3. xmlRequest.send();
  4. var xmlText = xmlRequest.responseText;
  5. alert(xmlText);//Aquí me muestra todo el texto del XML
  6. var xmlDocument = xmlRequest.responseXML;
  7. alert(xmlDocument);//Pero este alert no sale, como si hubiera un error en la linea anterior

El primer alert me muestra el XML completo como texto (perfecto, eso quiere decir que lo cargó), pero el segundo alert nunca llega a salir, es como si hubiera un error en la linea anterior.

Saludos
__________________
Los hombres pequeños, nunca se sienten pequeños; los hombres grandes, nunca se sienten grandes.

No sé quien fué el que dijo eso, pero está bueno.
  #10 (permalink)  
Antiguo 04/01/2012, 02:46
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: No carga el XML

más allá de lo obvio, verificar la consola del navegador, no sabría que más indicarte. sin un mensaje error muy claro es imposible determinar que esta sucediendo. el código lo veo bien... no tiene error sintáctico ni logísticos. ¿haz probado en un otro navegador o en todos fallan? ¿haz probado el modo asíncrono? ¿obtienes el mismo resultado?
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #11 (permalink)  
Antiguo 04/01/2012, 10:37
Avatar de Tecna  
Fecha de Ingreso: enero-2010
Mensajes: 291
Antigüedad: 14 años, 3 meses
Puntos: 45
Respuesta: No carga el XML

Buenas,

pudiera ser que el servidor no esté identificando el fichero como xml y por eso si que funcione responseText pero no responseXML. Comprueba el Content-Type con el método getResponseHeader().

Si ni siquiera llega a salir el alert pudiera ser que el navegador se haya quedado bloqueado y esto podría ser culpa del modo síncrono, ya que no sólo puede afectar el tamaño del fichero, pueden ocurrir cosas imprevistas como un fallo en la conexión al hacer la petición u otras como errores de código, que dejarían el navegador totalmente bloqueado. En general es recomendable usar el modo asíncrono. Si usas el método get incluye null como argumento del metodo send() para que no de problemas en algunos navegadores.

Intenta hacer distintas pruebas para ir acotando el problema y como te han dicho mira los errores de la consola, también es muy útil usar las excepciones. Otra cosa que puedes comprobar es que el fichero xml esté bien formado y que incluya su caracter de fin de fichero como tienen que tener todos los ficheros de texto, esto puede dar muchos problemas raros y es muy común y dificil de detectar.

No me había dado cuenta que lo quieres para un menú, que es lo peor para lo que se puede usar en cuanto a accesibilidad. El mal uso de ajax y javascript puede dejar una página inaccesible.
  #12 (permalink)  
Antiguo 04/01/2012, 22:34
Avatar de jorgelpadronb  
Fecha de Ingreso: agosto-2011
Ubicación: Cuba
Mensajes: 281
Antigüedad: 12 años, 8 meses
Puntos: 37
Respuesta: No carga el XML

YA LO LOGRAMOS HERMANOS.

Gracias a ustedes fuí armando la maquinaria y quedó así:

Código Javascript:
Ver original
  1. var Menu = new Array;
  2.  
  3.  function LoadItems(){           
  4.      var xmlRequest = new XMLHttpRequest();
  5.      xmlRequest.open("GET", 'Menu.xml', false);
  6.      xmlRequest.send(null);
  7.      var xmlText = xmlRequest.responseText;
  8.      var xmlResult = xmlRequest.responseXML;
  9.      var xmlList = xmlResult.getElementsByTagName('Item');
  10.      var i = 0;
  11.      var count = xmlList.length;
  12.      var itm = null;
  13.      for(i=0;i<count;i++){
  14.         itm = xmlList.item(i);
  15.         Menu[i] = new Array;
  16.         Menu[i]['Id'] = itm.getAttribute('Id');
  17.         Menu[i]['Text'] = itm.getAttribute('Text');
  18.         Menu[i]['Link'] = itm.getAttribute('Link');
  19.         Menu[i]['Title'] = itm.getAttribute('Title');
  20.         Menu[i]['Inside'] = itm.getAttribute('Inside');
  21.     }
  22.  }

Ya funciona super OK. El problema estaba en el XML. Tenía atributos sin "". El problema es que yo pensaba que era como HTML, que los atributos numéricos se ponen sin "". Gracias a que Tecna mencionó que el XML debía estar bien formado, me puse a investigar y dí con las diferencias entre HTML y XML. Una de las diferencias es esa, que en XML todos los atributos van entre "", aunque sean números.

10000000000000000000000000000000000000000000 de gracias para ustedes. Ojalá pudieran ser $ JAJAJA.

Muchas gracias a ambos por su ayuda.

Saludos.
__________________
Los hombres pequeños, nunca se sienten pequeños; los hombres grandes, nunca se sienten grandes.

No sé quien fué el que dijo eso, pero está bueno.

Última edición por jorgelpadronb; 04/01/2012 a las 22:42

Etiquetas: xml
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 04:25.