Jump to content


Photo

[RESUELTO] Crear archivo XML con TXMLDocument


  • Please log in to reply
24 replies to this topic

#1 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 21 October 2010 - 04:18 PM

Que tal foro,
les comento, en estos momentos hago una simple aplicación que genera un archivo XML para ser leída por otra, hasta acá todo bien.

El detalle es que no estoy usando componentes, sino creando una instancia de la clase TXMLDocument.

El problema que me ha generado es al intentar crear los nodos, puesto que para estos estoy usando la interfaz IXMLNode.

He tratado de basarme en algunos ejemplos de internet pero hasta ahora no doy con buenos resultados  :s

Este es el procedimiento en el que trato de generar dicho archivo



delphi
  1. procedure TFrmPreguntas.crearXML(Participante: String; IdPregunta,
  2.   ValRespuesta: Integer);
  3. var archivoXML: TXMLDocument;
  4.     nNodo, pNodo: IXMLNode;
  5. begin
  6.   archivoXML := TXMLDocument.Create(Nil);
  7.   archivoXML.Active := True;
  8.   nNodo := pNodo.AddChild('pregunta');
  9.   nNodo.Attributes['idpregunta'] := IdPregunta;
  10.   nNodo.Attributes['respuesta'] := ValRespuesta;
  11.   pNodo := nNodo.AddChild('participante');
  12.   pNodo.Attributes['nombre'] := Participante;
  13.   archivoXML.SaveToFile(ExtractFilePath(Application.ExeName) + Participante + '.xml');
  14.   archivoXML := Nil;
  15. end;



De esta forma, siempre me genera un Access Violation al intentar crear el hijo al nodo.

No tengo mucha experiencia en el asunto, espero sus comentarios  :)



Saludos!
  • 0

#2 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 posts
  • LocationEspaña

Posted 21 October 2010 - 04:34 PM

Buenas,

Yo no tengo experiencia en esto, pero quizás esto te sirva http://delphi.about....ype_txmldoc.htm

Nos leemos

  • 0

#3 Héctor Randolph

Héctor Randolph

    501st Legion

  • Moderadores
  • PipPipPip
  • 664 posts
  • LocationMéxico

Posted 21 October 2010 - 04:37 PM

Hola felipe

No lo he probado pero creo que se debe crear así



delphi
  1.   archivoXML := TXMLDocument.Create(Nil);
  2.   archivoXML.Active := True;
  3.   nNodo := archivoXML.AddChild('pregunta');  // Así se debería crear el nodo
  4.   nNodo.Attributes['idpregunta'] := IdPregunta;



Saludos
  • 0

#4 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 22 October 2010 - 07:42 AM

Gracias por el enlace [shadow=black,left]cadetill[/shadow],
[shadow=black,left]Hector[/shadow], había intentado esa propiedad antes pero no la asignaba al nodo, de la forma en que lo expones funciona sin problemas  (y)

Este es el resultado hasta ahora:



delphi
  1. <pregunta idpregunta="10" respuesta="50">
  2. <participante nombre="felipe"/>
  3. </pregunta>




Seguiré haciendo pruebas y no dudaré en preguntar  :D



Saludos!
  • 0

#5 enecumene

enecumene

    Webmaster

  • Administrador
  • 7419 posts
  • LocationRepública Dominicana

Posted 22 October 2010 - 07:52 AM



delphi
  1. procedure crearXML(Participante: String; IdPregunta, ValRespuesta: Integer);
  2. var archivoXML: TXMLDocument;
  3.     nNodo: IXMLNode;
  4. begin
  5.   archivoXML := TXMLDocument.Create(Application);
  6.     try
  7.       archivoXML.Active := True;
  8.       archivoXML.AddChild('pregunta');
  9.       nNodo :=  archivoXML.DocumentElement.AddChild('idpregunta');
  10.       nNodo.Attributes['idpregunta']  :=  IntToStr(IdPregunta);
  11.       nNodo :=  archivoXML.DocumentElement.AddChild('respuesta');
  12.       nNodo.Attributes['respuesta']  :=  IntToStr(ValRespuesta);
  13.       nNodo := archivoXML.DocumentElement.AddChild('participante');
  14.       nNodo.Attributes['participante']  := Participante;
  15.       archivoXML.SaveToFile(ExtractFilePath(Application.ExeName) + Participante + '.xml');
  16.     finally
  17.       archivoXML.Free;
  18.     end;
  19. end;



Lo hice al vuelo asi que puede contener errores :D :D

Saludos.
  • 0

#6 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 22 October 2010 - 07:56 AM

Pues mira lo curioso enecumene, solamente cambié la linea que propone Hector y no tuve que modificar más.
Sin embargo veré la propuesta a ver que resultado obtengo, pienso que la estructura puede cambiar.


Saludos!
  • 0

#7 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 22 October 2010 - 08:01 AM

Y este fué el resultado:



xml
  1. <pregunta>
  2. <idpregunta idpregunta="10"/>
  3. <respuesta respuesta="50"/>
  4. <participante participante="felipe"/>
  5. </pregunta>



(y)


PD: Falta etiquetas para HTML


Saludos!
  • 0

#8 enecumene

enecumene

    Webmaster

  • Administrador
  • 7419 posts
  • LocationRepública Dominicana

Posted 22 October 2010 - 08:31 AM

PD: Falta etiquetas para HTML


Colega, aqui tenemos hasta de xml ;)
  • 0

#9 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 22 October 2010 - 08:41 AM


PD: Falta etiquetas para HTML


Colega, aqui tenemos hasta de xml ;)


Ah chanfle... no las había visto :p


Saludos!
  • 0

#10 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 24 October 2010 - 08:53 PM

De nuevo al tema  *-)... vengo con otra duda, en este caso al cargar el archivo.

Pasa lo siguiente, tengo este código:



delphi
  1.   for i := 0 to archivos.Count - 1 do
  2.     begin
  3.       archivoXML := TXMLDocument.Create(Nil);
  4.       archivoXML.LoadFromFile(ExtractFilePath(Application.ExeName) + archivos[i]);
  5.       archivoXML.Active := True;
  6.       nNodo := archivoXML.DocumentElement.ChildNodes.First; // Invalid pointer operation
  7.       gridDatos.Cells[1,i] := archivoXML.DocumentElement.Attributes['nombre']; // No active document
  8.       //... etc, etc



gridDatos es un StringGrid donde voy a mostrar lo contenido en el XML, pero cuando intento cargar un simple texto del atributo nombre que posee el archivo, me sale el error: No active document.

Esto por una parte... en otras pruebas (evitando lo anterior, claro) si el ciclo for pasa a una segunda iteración, obtengo un error al asignar el valor a la variable nNodo, el cual dice: Invalid pointer operation

¿Alguna idea y/o sugerencia?


Saludos!
  • 0

#11 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14448 posts
  • LocationMéxico

Posted 25 October 2010 - 07:51 AM

Y porque lo estas creando cada vez que entras al for no seria mejor crearlo y luego entrar al bucle ?



delphi
  1.   archivoXML := TXMLDocument.Create(Nil);
  2.   archivoXML.LoadFromFile(ExtractFilePath(Application.ExeName) + archivos[i]);
  3.   archivoXML.Active := True;
  4. for i := 0 to archivos.Count - 1 do
  5.     begin
  6.       nNodo := archivoXML.DocumentElement.ChildNodes.First; // Invalid pointer operation
  7.       gridDatos.Cells[1,i] := archivoXML.DocumentElement.Attributes['nombre']; // No active document
  8.       //... etc, etc



Salud OS
  • 0

#12 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 25 October 2010 - 08:41 AM

Y porque lo estas creando cada vez que entras al for no seria mejor crearlo y luego entrar al bucle ?



delphi
  1.   archivoXML := TXMLDocument.Create(Nil);
  2.   archivoXML.LoadFromFile(ExtractFilePath(Application.ExeName) + archivos[i]);
  3.   archivoXML.Active := True;
  4. for i := 0 to archivos.Count - 1 do
  5.     begin
  6.       nNodo := archivoXML.DocumentElement.ChildNodes.First; // Invalid pointer operation
  7.       gridDatos.Cells[1,i] := archivoXML.DocumentElement.Attributes['nombre']; // No active document
  8.       //... etc, etc



Salud OS


Que tal amigo,
en un principio lo tenía así, pero dado que por cada ciclo se debe cargar un archivo diferente me daba error luego de hacer:

archivoXML.Active := False;

e intentar cargar nuevamente el archivo siguiente, la solución fue crearlo de nuevo por cada ciclo, ya que según me daba a entender dicha instancia quedaba inservible  ^o|


Saludos!
  • 0

#13 enecumene

enecumene

    Webmaster

  • Administrador
  • 7419 posts
  • LocationRepública Dominicana

Posted 26 October 2010 - 09:54 AM

Hola, Archivos es un OpenDialog??.

Saludos.
  • 0

#14 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 26 October 2010 - 10:08 AM

Hola, Archivos es un OpenDialog??.

Saludos.


Es un StringList, allí se guardan los nombres de los archivos, ej: archivo1.xml, archivo2.xml...


Saludos!
  • 0

#15 enecumene

enecumene

    Webmaster

  • Administrador
  • 7419 posts
  • LocationRepública Dominicana

Posted 26 October 2010 - 10:22 AM



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var i,n: integer;
  3.     MiXML: TXMLDocument;
  4.     Nodo: IXMLNode;
  5. begin
  6.   MiXML :=  TXMLDocument.Create(self);
  7.     for I := 0 to Archivos.Count - 1 do
  8.       MiXML.LoadFromFile(ExtractFilePath(Application.ExeName)+Archivos.Strings[i]);
  9.         for n := 0 to MiXML.ChildNodes.Count - 1 do
  10.           gridDatos.Cells[1,i] := MiXML.ChildNodes.Nodes[i].Text;
  11.           //etc etc
  12. end;



Por ahi puede andar el asunto.

Saludos
  • 0

#16 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 26 October 2010 - 10:57 AM



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var i,n: integer;
  3.     MiXML: TXMLDocument;
  4.     Nodo: IXMLNode;
  5. begin
  6.   MiXML :=  TXMLDocument.Create(self);
  7.     for I := 0 to Archivos.Count - 1 do
  8.       MiXML.LoadFromFile(ExtractFilePath(Application.ExeName)+Archivos.Strings[i]);
  9.         for n := 0 to MiXML.ChildNodes.Count - 1 do
  10.           gridDatos.Cells[1,i] := MiXML.ChildNodes.Nodes[i].Text;
  11.           //etc etc
  12. end;



Por ahi puede andar el asunto.

Saludos


Pues no necesariamente, si a un ciclo por los nodos te refieres, en mi código hago esto:



delphi
  1. while nNodo <> nil do
  2.   begin
  3.     gridDatos.Cells[j,i+1] := nNodo.Attributes['respuesta'];
  4.     j := j + 1;
  5.     nNodo := nNodo.NextSibling;
  6.   end;



Además el error no sale de allí :).



Saludos!
  • 0

#17 enecumene

enecumene

    Webmaster

  • Administrador
  • 7419 posts
  • LocationRepública Dominicana

Posted 26 October 2010 - 11:14 AM

Pues...


delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var i,n: integer;
  3.     MiXML: TXMLDocument;
  4.     Nodo: IXMLNode;
  5. begin
  6.   MiXML :=  TXMLDocument.Create(self);
  7.     for I := 0 to Archivos.Count - 1 do begin
  8.       MiXML.LoadFromFile(ExtractFilePath(Application.ExeName)+Archivos.Strings[i]);
  9.       Nodo := MiXML.ChildNodes.First;
  10.         while Nodo <> nil do
  11.           begin
  12.           //etc etc
  13.           end;
  14.     end;
  15. end;



Prueba con eso.

Saludos.
  • 0

#18 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 26 October 2010 - 03:02 PM

No funciona amigo, al usar esta declaración:



delphi
  1. Nodo := MiXML.ChildNodes.First;



Y luego intentar esto:



delphi
  1. gridDatos.Cells[j,i+1] := nNodo.Attributes['respuesta'];



Da error, porque al parecer no encuentra valor para ese atributo, a lo cual retorna nulo.


Saludos!
  • 0

#19 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4483 posts
  • LocationVenezuela

Posted 26 October 2010 - 03:27 PM

No funciona amigo, al usar esta declaración:



delphi
  1. Nodo := MiXML.ChildNodes.First;



Y luego intentar esto:



delphi
  1. gridDatos.Cells[j,i+1] := nNodo.Attributes['respuesta'];



Da error, porque al parecer no encuentra valor para ese atributo, a lo cual retorna nulo.


Saludos!


Asumo que cuando declaras Nodo := y luego haces nNodo := es error de escritura
  • 0

#20 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 26 October 2010 - 04:09 PM

Asumo que cuando declaras Nodo := y luego haces nNodo := es error de escritura


Ah no claro... corrijo :D, es que ahí solo copié y pegué lo que puso Fernando.

Obviamente el código original no tiene esos problemas de escritura.


Saludos!
  • 0




IP.Board spam blocked by CleanTalk.