Ir al contenido


Foto

[RESUELTO] Crear archivo XML con TXMLDocument


  • Por favor identifícate para responder
24 respuestas en este tema

#1 felipe

felipe

    Advanced Member

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 21 octubre 2010 - 04:18

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 mensajes
  • LocationEspaña

Escrito 21 octubre 2010 - 04:34

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

  • Moderador
  • PipPipPip
  • 664 mensajes
  • LocationMéxico

Escrito 21 octubre 2010 - 04:37

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

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 22 octubre 2010 - 07:42

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
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 22 octubre 2010 - 07:52



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

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 22 octubre 2010 - 07:56

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

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 22 octubre 2010 - 08:01

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
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 22 octubre 2010 - 08:31

PD: Falta etiquetas para HTML


Colega, aqui tenemos hasta de xml ;)
  • 0

#9 felipe

felipe

    Advanced Member

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 22 octubre 2010 - 08:41


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

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 24 octubre 2010 - 08:53

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
  • 14.259 mensajes
  • LocationMéxico

Escrito 25 octubre 2010 - 07:51

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

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 25 octubre 2010 - 08:41

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
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 26 octubre 2010 - 09:54

Hola, Archivos es un OpenDialog??.

Saludos.
  • 0

#14 felipe

felipe

    Advanced Member

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 26 octubre 2010 - 10:08

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
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 26 octubre 2010 - 10:22



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

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 26 octubre 2010 - 10:57



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
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 26 octubre 2010 - 11:14

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

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 26 octubre 2010 - 03:02

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

  • Moderador
  • PipPipPip
  • 4.483 mensajes
  • LocationVenezuela

Escrito 26 octubre 2010 - 03:27

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

  • Moderador
  • PipPipPip
  • 3.283 mensajes
  • LocationColombia

Escrito 26 octubre 2010 - 04:09

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