Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 27-06-2012
Avatar de M.L.Casellas
M.L.Casellas M.L.Casellas is offline
Miembro
NULL
 
Registrado: sep 2011
Posts: 23
Poder: 0
M.L.Casellas Va por buen camino
Post Busqueda de un ISBN en DILVE por llamadas HTTP a su API (respuesta en XML)

Hola;


Abro este nuevo hilo, porque considero que es mejor a la hora de que alguien busque información sobre este tema. En un anterior hilo (http://clubdelphi.com/foros/showthread.php?t=79288) pedía ayuda para leer los ficheros .xml que DILVE devuelve al hacerle llamadas http. El título de ese hilo no es descriptivo para el tema en cuestión y además es algo lioso, lo siento.


Y también, para colaborar y poder ayudar a otros aquí en la comunidad


Así que, aquí va este hilo que es la forma en que ya he solucionado el problema, y para que pueda servir a alguien más que en un futuro necesite programar (para una librería por ejemplo, como es mi caso) llamadas a DILVE.


Así es como yo he conseguido hacerlo al final, y va estupendamente, al instante, en 1 segundo tengo los datos que quiero del ISBN solicitado, es una maravilla


Bueno, al grano:


Después de comprarme y leerme la mitad del libro XML-Edición 2012 de Miguel Ángel Acera García, buscar info por internet etc…etc…He conseguido aprender bastante sobre el XML y como tratarlo en Delphi.


El asunto en cuestión es pedir a DILVE los datos de un libro, enviándoles el código ISBN. Si la llamada es correcta, ellos devuelven un fichero en formato .XML con la ficha de dicho libro.
DILVE trabajan con el formato internacional ONIX for Books (Del cual me he bajado y leido parte de la documentación).


Bien, lo primero que hago es la llamada a la URL con los parametros adecuados:


URL de DILVE + La llamada “getRecordsX” que es la que pide un sólo registro + Nombre de usuario + Contraseña + Identificador(el ISBN/Cod.Barras) + El formato que deseamos (ONIX etiquetas largas, ONIX, etiquetas cortas, CSV….) + La versión que queremos (DILVE trabaja internamente con la 2.1 que ya es antigua, pero también sirve la 3.0 que es la actual).


Después ejecuto el procedure que he creado para la carga de los datos:
Código Delphi [-]
  XmlToMe(XMLDocument1.DocumentElement);


Y el procedure es el siguiente (va con comentarios):
Código Delphi [-]
 procedure TFormPrincipal.XmlToKios(XmlNode: IXMLNode);
var
  I:  Integer;
  I2: Integer;
  NodeText: String;
  AttrNode: IXMLNode;
   Atributos: String;
  AutorPerson, AutorPersonInverted: Boolean;

begin
     AutorPerson := False;
    AutorPersonInverted := False;
     

  // Desechamos nodos que no sean elements
  

  if XmlNode.NodeType <>  ntElement then
      Exit;
    

  // Asignamos el nombre del nodo a la variable
  NodeText:=  XmlNode.NodeName;
   

  // Comprobamos si la cabecera es correcta o devuelve error
   

 if XmlNode.NodeName = 'ONIXMessage' then
         for I := 0 to  XmlNode.AttributeNodes.Count - 1 do   // leemos los parametros
              begin
                 AttrNode:= XmlNode.AttributeNodes.Nodes[i];
       Atributos := Atributos + ' ' + AttrNode.NodeName + '=' + '"' + AttrNode.Text +  '"';
             end;
    


Caption := Caption +  ' <' + XmlNode.NodeName +  Atributos + '>';
    


end;
 
  
  // Si la respuesta es error, se muestra un  mensaje con el código y texto  del error
    

  if XmlNode.NodeName = 'error' then
       begin
           errores :=  True;
       end;
 
  
   // Comprobamos el tipo de notificación. '03' es para fichas completas.  El
    // resto pueden ser updates y otros...
     // la etiqueta 'Product' es repetible si se piden listados, en este caso  es
     // Existen etiquetas que se llaman igual dentro de distintos bloques,  por
    // lo que hay que comprobar que cuelgan del adecuado
     if (XmlNode.NodeName = 'NotificationType') and
          (XmlNode.ParentNode.NodeName = 'Product') then
           begin
               if Not  (XmlNode.NodeValue = '03') then
                   begin
                       ShowMessage('No  se trata de una ficha completa de libro');
                       errores :=  True;
                   end;
          end;
 
  
   // Ahora ya comenzamos a leer los campos que nos interesan
    

  // TITULO
 
  
   if (XmlNode.NodeName = 'TitleDetail') and
           (XmlNode.ParentNode.NodeName = 'DescriptiveDetail') and
           (XmlNode.ParentNode.ParentNode.NodeName = 'Product') and
           (XmlNode.ChildNodes['TitleType'].Text = '01') then
            begin
                 XmlNode := XmlNode.ChildNodes['TitleElement'];
                if  XmlNode.ChildNodes['TitleElementLevel'].Text = '01' then
                     begin
                        EditTitulo.Text :=  XmlNode.ChildNodes['TitleText'].Text;
                    end;
           end;
 
  
  // AUTOR/ES
 
  
  // Aquí pueden estar las dos etiquetas a la vez: inverted y normal
    //  me decanto por la Inverted
    

  if (XmlNode.NodeName = 'Contributor') and
    (XmlNode.ParentNode.NodeName = 'DescriptiveDetail') and
         (XmlNode.ParentNode.ParentNode.NodeName = 'Product') and
    (XmlNode.ChildNodes['ContributorRole'].Text = 'A01') then
          begin
               //Recorremos todos los child para ver los que hay
              for I2 :=  0 to XmlNode.ChildNodes.Count - 1 do
                    begin 
                        if  XmlNode.ChildNodes[I2].NodeName = 'PersonName' then
                             begin
                                AutorPerson := True;
                            end;
                if XmlNode.ChildNodes[I2].NodeName = 'PersonNameInverted'  then
                    begin
                        AutorPersonInverted :=  True;
                    end;
             end;
 
  
// Según las etiquetas, si está la opción Inverted la utlizamos  prioritariamente
 
      
  if AutorPersonInverted then
    begin
               if  EditAutores.GetTextLen > 0 then
                   begin
                        EditAutores.Text := EditAutores.Text + ' | ' +  XmlNode.ChildNodes['PersonNameInverted'].Text;
                   end  else
                   begin
          EditAutores.Text :=  XmlNode.ChildNodes['PersonNameInverted'].Text;
                   end;
            end else
         if AutorPerson then
             begin
                 if  EditAutores.GetTextLen > 0 then
                     begin
                          EditAutores.Text := EditAutores.Text + ' | ' +  XmlNode.ChildNodes['PersonName'].Text;
                     end else
                        begin
                           EditAutores.Text :=  XmlNode.ChildNodes['PersonName'].Text;
                       end;
             end;
        end;
 
  
// EDITORIAL
 
  
if (XmlNode.NodeName = 'Publisher') and
        (XmlNode.ParentNode.NodeName = 'PublishingDetail') and
        (XmlNode.ParentNode.ParentNode.NodeName = 'Product') and
   (XmlNode.ChildNodes['PublishingRole'].Text = '01') then
         begin
              EditCodEditorial.Text :=  XmlNode.ChildNodes['PublisherIdentifier'].ChildNodes['IDValue'].Text;
              EditEditorial.Text := XmlNode.ChildNodes['PublisherName'].Text;
         end;
 
   
// PRECIO CON IVA
      if (XmlNode.NodeName = 'Price') and
           (XmlNode.ParentNode.NodeName  = 'SupplyDetail') and
           (xmlNode.ParentNode.ParentNode.NodeName =  'ProductSupply') and
           (XmlNode.ParentNode.ParentNode.ParentNode.NodeName  = 'Product') and
      (XmlNode.ChildNodes['CurrencyCode'].Text = 'EUR')  and
      (XmlNode.ChildNodes['PriceType'].Text = '04') then
              begin
                 EditPvp.Text := XmlNode.ChildNodes['PriceAmount'].Text  + '  €';
             end;
 
    
// EL IVA (%)
   

  if (XmlNode.NodeName = 'Tax') and
          (XmlNode.ParentNode.NodeName =  'Price') and
          (XmlNode.ParentNode.ParentNode.NodeName = 'SupplyDetail')  and
          (XmlNode.ParentNode.ParentNode.ParentNode.NodeName =  'ProductSupply') and
           (XmlNode.ParentNode.ParentNode.ParentNode.ParentNode.NodeName = 'Product')  and
          (XmlNode.ChildNodes['TaxType'].Text = '01') then
             begin
                EditIva.Text := XmlNode.ChildNodes['TaxRatePercent'].Text + '   %';
            end;
 

  // Recorremos los nodos hijos si lo hay
      if XmlNode.HasChildNodes  then
     for I := 0 to XmlNode.ChildNodes.Count - 1 do
             XmlToKios(XmlNode.ChildNodes.Nodes[i]);
 
  // Si ha habido errores, limpiamos los edits
     if errores then
     begin
            LimpiarCampos.Execute;
         end;
 
  
  // Deberiamos capturar el error enviado por el servidor en formato  .xml
    // y mostrar el mensaje adecuado, según la tabla de DILVE, ya que  estos
    // pueden ser de conexión, mantenimiento del servidor, isbn no  encontrado,
    // isbn mal formado, etc.
     // ¿Que tal si preguntamos en el ClubDelphi? ¡Vale! Vamos allá.......


end;


Lo que hago es recorrer el documento. Apenas tarda un segundo (se tarda mucho más en dar de alta el libro a mano).


Decir que hay campos (nodos) que son repetibles y ya dependen de otros nodos hijo, del código que lleven.


Me falta alguna cosilla en realidad, y se trata del tema de errores. Veréis: si hago esta llamada desde el Internet Explorer y el ISBN o existe por ejemplo, pues el IE se queda en blanco, mostrando una pantalla de error propia, pero no recoge el .xml de error que envía DILVE (ya meré en ver código fuente de la página)……. ¡Firefox si lo hace! Firefox si, y así pude recoger el .xml en cuestión para ver como era.


Entonces, yo me preguntaba que ocurriría en mi codigo……pues…..al estilo IE …no me llega el .xml de error.
Lo suyo sería poder recoger ese .xml de error y procesarlo según la tabla de errores de DILVE, para saber si es por mantenimiento del servidor, isbn no encontrado, etc. De momento, pues muestro un error general.



¿Alguien sabe hacer para que mi llamada recoja el .xml de error? Ese .xml lleva la cabecera como el otro, pero después sólo lleva 2 datos: el número de error y una descripción (en inglés).


Bueno, espero que esto pueda servir de ayuda a alguien. Por supuesto, para probarlo hace falta tener User y Password de DILVE. Yo utilizo la de la librería para quien hago esto. Pero aquí queda, para quien llegara a encontrarse en mi situación y buscara info.




Y por supuesto, seguro que este código es mejorable, así que cualquier consejo, sugerencia, lo que sea, lo agradecería

¡Un saludo!
Responder Con Cita
  #2  
Antiguo 27-06-2012
Avatar de M.L.Casellas
M.L.Casellas M.L.Casellas is offline
Miembro
NULL
 
Registrado: sep 2011
Posts: 23
Poder: 0
M.L.Casellas Va por buen camino
Exclamation

Un pequeño apunte:

Al principio he llamado al procedure 'DilveToMe' (XmlToMe(XMLDocument1.DocumentElement) Y después en el código completo del procedure lo llamé 'DilveToKios'. Ha sido un fallo mio al teclear, ha de ser lo mismo...sorry
Responder Con Cita
  #3  
Antiguo 27-06-2012
Avatar de chamix
chamix chamix is offline
Registrado
NULL
 
Registrado: may 2012
Posts: 8
Poder: 0
chamix Va por buen camino
¡Me alegro de que hayas visto la luz!

Desde mi ignorancia, te diría lo siguiente:

¿Has probado a hacer la llamada desde un TWebBrowser? veo que cargas el fichero directamente en el XMLDocument, quizás usando tu propio browser funcione ¿? Por probar...

¿Has probado las otras opciones que te da DILVE? no tengo ni idea de como funciona, pero he visto que puedes descargar los datos de otras formas (FTP, EMail...) además de las llamadas URL.

Y por último. Has preguntado a DILVE, según dicen, tienen un servicio de ayuda gratuito y por lo que estás diciendo, seguro que alguien más les ha preguntado por ese error, porque supongo que habrá algún otro usuario que use explorer...

**Lo del error de escritura es lo primero que se ve al buscar el procedimiento :-) pero creo que se entiende perfectamente.

Saludos y suerte!
Responder Con Cita
  #4  
Antiguo 28-06-2012
Avatar de M.L.Casellas
M.L.Casellas M.L.Casellas is offline
Miembro
NULL
 
Registrado: sep 2011
Posts: 23
Poder: 0
M.L.Casellas Va por buen camino
Post

Gracias de nuevo, chamix...

Acabo de probar con el TWebBrowser y se comporta como el IE

De todas formas estudiaré a ver las opciones del TWebBrower que también es un desconocido para mi. La verdad es que hasta ahora no he tenido que hacer nada relacionado con internet.

También se me ocurre con lo que comentas, que en el caso de error pues también puedo descargar el fichero por ftp. Solamente en los casos de error para poder procesarlo correctamente.

Lo hago directamente con el componente XMLDocument para mayor rapidez y sencillez. De momento pienso eso, sólo en caso de error, optar por bajar el fichero (hasta que si es posible, encontrar la forma de trabajarlo con el mismo XMLDocument).


¡Un saludo!
Responder Con Cita
  #5  
Antiguo 28-06-2012
Avatar de M.L.Casellas
M.L.Casellas M.L.Casellas is offline
Miembro
NULL
 
Registrado: sep 2011
Posts: 23
Poder: 0
M.L.Casellas Va por buen camino
Smile

Ah, en cuanto a lo de contactar con DILVE, ya lo hice también y me aclararon un par de dudas que tenía (nada que ver con Delphi, claro.). Todo por e-mail, aunque podría haber hablado por teléfono desde la librería, ya que son usuarios (para los no-usuarios solamente es posible con e-mail). Pero vamos, me respondieron en menos de 24 horas y muy amables y serviciales. De hecho ya hablé hace un tiempo, cuando supe de DILVE, por teléfono y lo mismo, muy atentos.
Responder Con Cita
  #6  
Antiguo 28-06-2012
Avatar de chamix
chamix chamix is offline
Registrado
NULL
 
Registrado: may 2012
Posts: 8
Poder: 0
chamix Va por buen camino
¿Has probado a hacer la llamada vía FTP directamente? si lo carga vía URL no veo porque no lo iba a hacer de esta manera.

XMLDocument1.LoadFromFile(‘userass@FTP://ftp.dilve.es/loqueseaquevengadespues’);

te escribo lo primero que se me ocurre... Pero ¿quien sabe?
Responder Con Cita
  #7  
Antiguo 28-06-2012
Avatar de M.L.Casellas
M.L.Casellas M.L.Casellas is offline
Miembro
NULL
 
Registrado: sep 2011
Posts: 23
Poder: 0
M.L.Casellas Va por buen camino
Question

No lo tengo claro si se puede pedir por ftp un registro sólo. Mañana lo consultaré con DILVE y ya os cuento. Ahora (que ya son la 01:00 de la madrugada casi :P ) me voy al catre jeje.

Bye! :-)
Responder Con Cita
  #8  
Antiguo 29-06-2012
Avatar de M.L.Casellas
M.L.Casellas M.L.Casellas is offline
Miembro
NULL
 
Registrado: sep 2011
Posts: 23
Poder: 0
M.L.Casellas Va por buen camino
Thumbs up

Hola;

Ya me han respondido en DILVE acerca del error. La respuesta que me han dado es esta:

"
Efectivamente, en el caso de las llamadas getRecordListX, getRecordStatusX y getRecordsX, deberíamos devolver en casi todos los casos un HTTP Status 200 ya que el error se indica dentro del XML de la respuesta.

Incluiremos esta modificación en próximas versiones y le avisaremos cuando esté disponible (seguramente en 3 semanas). Le pedimos disculpas por los inconvenientes que este error haya podido causarle. "


Claro, supongo que así si llegará el documento .xml de error, ya que es status será correcto. Pues nada, esperaremos para controlar los errores


¡Un saludo!
Responder Con Cita
  #9  
Antiguo 13-07-2012
Avatar de M.L.Casellas
M.L.Casellas M.L.Casellas is offline
Miembro
NULL
 
Registrado: sep 2011
Posts: 23
Poder: 0
M.L.Casellas Va por buen camino
Thumbs up

Bueno, pues ya han corregido el http status que envian, tal como me dijeron. Ahora ya se recibe bien el xml de error. Ya hace una semana más o menos que me avisaron, pero se me pasó contarlo aquí. La verdad es que son muy serviciales estos de DILVE

Pues nada, sólo quería contarlo, fin de la historia, jeje. O bueno, lo dejaremos como Holmes en la segunda parte: The End ?

¡Un saludo!
Responder Con Cita
  #10  
Antiguo 13-07-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.043
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Gracias por contarlo
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Tiempos de Respuesta Maury Manosalva MySQL 2 01-02-2007 17:59:46
codigos ISBN Onti Varios 4 06-10-2003 00:53:07
La mejor respuesta de Exámen. obiwuan Humor 1 08-08-2003 19:09:39
Respuesta danytorres Varios 2 16-07-2003 20:55:43


La franja horaria es GMT +2. Ahora son las 19:51:55.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi