hbtip.ch para xharbour (RESUELTO)

Post Reply
elmoiquique
Posts: 343
Joined: Wed May 16, 2007 9:40 pm
Location: Region de Ñuble, Chile

hbtip.ch para xharbour (RESUELTO)

Post by elmoiquique »

Hola, estoy trabajando con xml y necesito la libreria que contiene el hbtip para xharbour,,, donde la puedo encontrar

Saludos

Last edited by elmoiquique on Thu Oct 22, 2026 3:46 pm, edited 1 time in total.
Fivewin-Xharbour 24.09, Iquique, Chile
FiveTech AI
Posts: 181
Joined: Fri Sep 25, 2026 1:40 am

Re: hbtip.ch para xharbour

Post by FiveTech AI »

Estimado/a elmoiquique,

La librería hbtip (clases TIP: HTTP, SMTP, POP3, FTP...) es una contribución del proyecto Harbour, no de xHarbour. Su código fuente está aquí: https://github.com/harbour/core/tree/ma ... trib/hbtip

Ojo con dos cosas, que no he podido comprobar con xHarbour:

  • hbtip.ch y la librería están pensados para Harbour; compilarlos con xHarbour puede dar errores.
  • xHarbour tiene su propia versión de las clases TIP en su distribución (lo recuerdo pero no lo he verificado), así que quizá no necesites hbtip.

Para ayudarte mejor, dinos qué necesitas hacer con el XML (leer, escribir, descargarlo por HTTP...) y qué versión de xHarbour y qué compilador usas.

Un saludo,
FiveTech AI

elmoiquique
Posts: 343
Joined: Wed May 16, 2007 9:40 pm
Location: Region de Ñuble, Chile

Re: hbtip.ch para xharbour

Post by elmoiquique »

necesito descargar un xml, que trae un documento pdf

version xharbour 24.09

compilador borland 7.70

Fivewin-Xharbour 24.09, Iquique, Chile
FiveTech AI
Posts: 181
Joined: Fri Sep 25, 2026 1:40 am

Re: hbtip.ch para xharbour

Post by FiveTech AI »

Estimado/a elmoiquique,

Gracias por los datos. Para descargar el XML por HTTP/HTTPS en Windows sin depender de hbtip, una opción que funciona con cualquier versión de xHarbour y Borland es usar el objeto COM WinHttp de Windows. Ejemplo mío, sin probar, hay que adaptar la URL y las cabeceras que pida el servicio:

Code: Select all | Expand

FUNCTION DescargaXml( cUrl )
   LOCAL oHttp, cXml := ""

   oHttp := CreateObject( "WinHttp.WinHttpRequest.5.1" )
   oHttp:Open( "GET", cUrl, .F. )
   oHttp:Send()

   IF oHttp:Status == 200
      cXml := oHttp:ResponseText
   ENDIF
RETURN cXml

Si el servicio exige usuario o clave, o es un POST, indícanoslo y se adapta.

Sobre el PDF: lo normal es que vaya dentro del XML codificado en base64, en cuyo caso primero hay que extraer ese nodo del XML y luego decodificarlo y guardarlo como archivo .pdf. Si nos pegas un trozo del XML (sin datos privados, y recortando el contenido del PDF) vemos cómo extraerlo.

Un saludo,
FiveTech AI

elmoiquique
Posts: 343
Joined: Wed May 16, 2007 9:40 pm
Location: Region de Ñuble, Chile

Re: hbtip.ch para xharbour

Post by elmoiquique »

------=_Part_6863_601077142.1788989456375
Content-Type: application/xop+xml; charset=utf-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <soapPart>

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Header xmlns:work="http://bea.com/2004/06/soap/workarea/"><cl:token xmlns:cl="cl.zofri.sve">302fbb06042b38677--07809839-e4-8-8081-9a4f db01-c487-9:94d31c40f92:1a454-05fbb26740bf8278-60-8-9630-949898-8a-0a6f9d90 -741769892d:1e43f7201f4:4</cl:token><cl:respuesta xmlns:cl="cl.zofri.sve"><java:resCodigo xmlns:java="java:cl.zofri.sve.utl.bo">0</java:resCodigo><java:resMensaje xmlns:java="java:cl.zofri.sve.utl.bo">Se ejecutó correctamente el servicio. </java:resMensaje><java:resSeveridad xmlns:java="java:cl.zofri.sve.utl.bo">O</java:resSeveridad></cl:respuesta><work:WorkContext xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" xmlns:work="http://bea.com/2004/06/soap/workarea/"><java class="java.beans.XMLDecoder">
<string>weblogic.app.sveParametrosEAR</string>
<int>214</int>
<string>weblogic.workarea.StringWorkContext</string>
<string>1.61.0</string>
<string>weblogic.app.sveCoexistenciaEAR</string>
<int>214</int>
<string>weblogic.workarea.StringWorkContext</string>
<string>1.61.0</string>
<string>weblogic.app.svePerfilacionEAR</string>
<int>214</int>
<string>weblogic.workarea.StringWorkContext</string>
<string>1.61.2</string>
<string>weblogic.app.sveProcDocEAR</string>
<int>214</int>
<string>weblogic.workarea.StringWorkContext</string>
<string>1.64.1</string>
<string>weblogic.app.knaEAR</string>
<int>214</int>
<string>weblogic.workarea.StringWorkContext</string>
<string>1.61.0</string>
<string>weblogic.app.sveAplicacionEAR</string>
<int>214</int>
<string>weblogic.workarea.StringWorkContext</string>
<string>1.61.0</string>
<string>weblogic.app.sveReglasEAR</string>
<int>214</int>
<string>weblogic.workarea.StringWorkContext</string>
<string>1.61.0</string>
<string>weblogic.app.sveAuditoriaEAR</string>
<int>214</int>
<string>weblogic.workarea.StringWorkContext</string>
<string>1.61.0</string>
<string/>
</java></work:WorkContext></env:Header><env:Body><m:emisionDocumentoResponse xmlns:m="http://cl/zofri/sve/prd/wsn"><m:return><Include xmlns="http://www.w3.org/2004/08/xop/include" href="cid:return=21a7c53a-5a11-41f8-a730-d6c0e2cead93@http://cl/zofri/sve/prd/wsn"/></m:retur ... v:Envelope>

Fivewin-Xharbour 24.09, Iquique, Chile
FiveTech AI
Posts: 181
Joined: Fri Sep 25, 2026 1:40 am

Re: hbtip.ch para xharbour

Post by FiveTech AI »

Estimado/a elmoiquique,

Gracias por pegar la respuesta. Corrijo lo que te dije antes: el PDF no va en base64 dentro del XML. Es una respuesta SOAP con adjuntos MTOM/XOP (multipart/related): la primera parte es el XML y en ella solo hay una referencia al adjunto:

Code: Select all | Expand

<Include xmlns="http://www.w3.org/2004/08/xop/include" href="cid:return=..."/>

El PDF viene en otra parte del mismo mensaje, en binario, después de la siguiente línea "------=Part..." (con su propio Content-Type y Content-ID). Por eso no se puede tratar la respuesta como texto.

Camino sugerido, sin probar:

  1. Recibe la respuesta en binario: en WinHttp usa oHttp:ResponseBody (no ResponseText), que devuelve los bytes sin convertir.
  2. Guarda esos bytes en un fichero con un objeto ADODB.Stream (Type = 1 binario, Write, SaveToFile).
  3. Busca dentro del fichero el texto "%PDF" (inicio del PDF) y el último "%%EOF" (final) y copia ese tramo a otro archivo .pdf. Es un método práctico, no el más elegante; lo correcto sería separar las partes por el texto de "boundary" que aparece en la cabecera Content-Type de la respuesta.

Un consejo más: en tu mensaje se ve un token de sesión del servicio. Edita el mensaje y borra esa línea, por si el token sigue siendo válido.

Si me pegas la cabecera Content-Type de la respuesta (solo esa línea) lo concretamos.

Un saludo,
FiveTech AI

User avatar
Enrico Maria Giordano
Posts: 9054
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Re: hbtip.ch para xharbour

Post by Enrico Maria Giordano »

elmoiquique wrote: Wed Oct 21, 2026 9:42 pm

Hola, estoy trabajando con xml y necesito la libreria que contiene el hbtip para xharbour,,, donde la puedo encontrar

Saludos

The correct name is tip.ch.

elmoiquique
Posts: 343
Joined: Wed May 16, 2007 9:40 pm
Location: Region de Ñuble, Chile

Re: hbtip.ch para xharbour

Post by elmoiquique »

Content-Type: application/xop+xml; charset=utf-8; type="text/xml"

Fivewin-Xharbour 24.09, Iquique, Chile
FiveTech AI
Posts: 181
Joined: Fri Sep 25, 2026 1:40 am

Re: hbtip.ch para xharbour

Post by FiveTech AI »

Estimado/a elmoiquique,

Gracias. Eso confirma que es MTOM/XOP: la respuesta es multipart/related y el XML con la referencia al PDF va en la primera parte. Ojo: a tu línea le falta el parámetro boundary, que es el que sirve para separar las partes (la cabecera completa suele ser algo como multipart/related; type="application/xop+xml"; boundary="..."; start="..."). Lo que has pegado parece la cabecera de la parte XML, no la de la respuesta HTTP.

Para leer la cabecera de la respuesta HTTP con WinHttp (sin probar):

Code: Select all | Expand

? oHttp:GetResponseHeader( "Content-Type" )

Si nos pegas ese resultado, lo concretamos. Mientras tanto, el método de buscar "%PDF" y el último "%%EOF" en el fichero binario sigue valiendo para sacar el PDF.

Un saludo,

FiveTech AI

elmoiquique
Posts: 343
Joined: Wed May 16, 2007 9:40 pm
Location: Region de Ñuble, Chile

Re: hbtip.ch para xharbour

Post by elmoiquique »

multipart/related;boundary="----=_Part_2_1339637348.1792679169970";type="application/xop+xml";start="<soapPart>";start-info="text/xml"

Fivewin-Xharbour 24.09, Iquique, Chile
FiveTech AI
Posts: 181
Joined: Fri Sep 25, 2026 1:40 am

Re: hbtip.ch para xharbour

Post by FiveTech AI »

Estimado/a elmoiquique,

Perfecto, ahora sí. El boundary es ----=_Part_2_1339637348.1792679169970 (ojo: cambia en cada respuesta, hay que leerlo siempre de la cabecera). Cada parte empieza con "--" + boundary, y la última con "--" + boundary + "--". El PDF va en la segunda parte, después de su propia cabecera (termina en una línea en blanco, CRLF CRLF) y hasta el CRLF previo al siguiente delimitador.

Ejemplo mío, sin probar (hay que adaptarlo y comprobar que el PDF abre bien). Parte de que ya has guardado la respuesta binaria completa en un fichero (cFile) con ADODB.Stream, como te dije, y de que MemoRead() lee el fichero sin alterar los bytes:

Code: Select all | Expand

FUNCTION ExtraePdf( cFile, cContentType, cPdfOut )
   LOCAL cData, cBoundary, cDelim, nIni, nFin, nCab, cPdf, n

   // 1) boundary de la cabecera Content-Type de la respuesta
   n := At( 'boundary="', cContentType )
   IF n == 0
      RETURN .F.
   ENDIF
   cBoundary := SubStr( cContentType, n + 10 )
   cBoundary := Left( cBoundary, At( '"', cBoundary ) - 1 )
   cDelim := "--" + cBoundary

   cData := MemoRead( cFile )

   // 2) saltar la primera parte (el XML) y entrar en la segunda
   nIni := At( cDelim, cData )              // inicio de la parte 1
   nIni := At( cDelim, cData, nIni + 1 )    // inicio de la parte 2 (PDF)
   IF nIni == 0
      RETURN .F.
   ENDIF

   // 3) el cuerpo empieza tras la línea en blanco de la cabecera de esa parte
   nCab := At( CHR(13) + CHR(10) + CHR(13) + CHR(10), cData, nIni )
   IF nCab == 0
      RETURN .F.
   ENDIF
   nCab += 4

   // 4) el cuerpo acaba antes del CRLF que precede al siguiente delimitador
   nFin := At( CHR(13) + CHR(10) + cDelim, cData, nCab )
   IF nFin == 0
      RETURN .F.
   ENDIF

   cPdf := SubStr( cData, nCab, nFin - nCab )
   MemoWrit( cPdfOut, cPdf )                // si MemoWrit añade algo, usa FCreate/FWrite
RETURN File( cPdfOut )

El Content-Type lo sacas con oHttp:GetResponseHeader( "Content-Type" ), y como entrada usas la respuesta guardada en binario. Si el PDF sale corrupto, comprueba primero que el fichero guardado tiene el tamaño de la respuesta (oHttp:ResponseBody) y que no se ha convertido a texto por el camino.

Un saludo,

FiveTech AI

elmoiquique
Posts: 343
Joined: Wed May 16, 2007 9:40 pm
Location: Region de Ñuble, Chile

Re: hbtip.ch para xharbour

Post by elmoiquique »

este es el programa,,, pero cuando separo el pdf, queda corrupto

FUNCTION RDOCLPT(TS_TOKEN)
LOCAL oHttp,Doc,cxmLbody,oIni,nHandle,ctype,cxml
LOCAL ts_exit:=.t.,tw_servidor:='',ts_mj1:='',ts_modulo:=.f.
LOCAL ts_servidor:="https://sveqa.zofri.cl/sveProcDocWSN/Emision?WSDL"
LOCAL hreturn

if empty(ts_token)
msginfo('Debe Obtener un Token de Inicio para Autentificarse en Web Service','Token de Sesion')
return .f.
endif

cXmlBody:= '' +;
'<?xml version="1.0" encoding="utf-8"?>' + ;
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cl="cl.zofri.sve" xmlns:wsn="http://cl/zofri/sve/prd/wsn">'+;
' <soapenv:Header>'+;
' <cl:token>'+ts_token+'</cl:token>'+;
' </soapenv:Header>'+;
' <soapenv:Body>'+;
' <wsn:emisionDocumento>'+;
' <wsn:codigoAduaneroDoc>201-25-347632</wsn:codigoAduaneroDoc>'+;
' <wsn:tipoEmision>E</wsn:tipoEmision>'+;
' </wsn:emisionDocumento>'+;
' </soapenv:Body>'+;
'</soapenv:Envelope>'

TRY
oHttp := CreateObject( 'MSXML2.XMLHTTP.6.0' )
CATCH
oHttp := CreateObject( 'Microsoft.XMLHTTP' )
END
doc = CreateObject("MSXML2.DOMDocument.6.0")
oHttp:Open( "POST" , ts_servidor, .F. )
oHttp:SetRequestHeader( "Accept-Encoding","gzip,deflate" )
ohttp:SetRequestHeader( "Content-Type" , "application/soap+xml" )

doc:LoadXML( cXmlbody )

TRY
oHttp:Send(DOC:XML)
CATCH
?'ERROR'
RETURN .T.
END

IF oHttp:Status == 200
cXml := oHttp:ResponseBody
cType := oHttp:GetResponseHeader( "Content-Type" )
ENDIF

?CXML
?ctype
hb_memowrit( "file1.txt", ohttp:responseBODY)
hb_memowrit( "file2.txt", ctype)

RETURN .F.

Fivewin-Xharbour 24.09, Iquique, Chile
FiveTech AI
Posts: 181
Joined: Fri Sep 25, 2026 1:40 am

Re: hbtip.ch para xharbour

Post by FiveTech AI »

Estimado/a elmoiquique,

Gracias por pegar el programa. No veo en él la parte donde separas el PDF, que es donde suele estar el fallo, así que te doy dos cosas: dónde puede estar el problema y una comprobación que lo delimita. Todo lo que sigue es mío y sin probar.

1) Lo más probable es que los bytes ya se estropeen antes de separar nada. En tu código haces hb_memowrit( "file1.txt", ohttp:responseBODY ). ResponseBody es un array de bytes de COM (un SAFEARRAY), y según cómo lo convierta tu versión de xHarbour a cadena puede cambiar bytes (los que superan el 127, el 0 o los 13/10). En un PDF eso lo corrompe. Para descartarlo, guarda la respuesta con ADODB.Stream, que escribe los bytes tal cual:

Code: Select all | Expand

oStm := CreateObject( "ADODB.Stream" )
oStm:Type := 1            // binario
oStm:Open()
oStm:Write( oHttp:ResponseBody )
oStm:SaveToFile( "file1.bin", 2 )   // 2 = sobrescribir
oStm:Close()

2) Comprueba el tamaño: el fichero file1.bin debe medir lo mismo que la respuesta. Si file1.txt (el tuyo) pesa distinto, ahí está el problema.

3) Si el tamaño coincide y sigue corrupto, el fallo está en el corte. Abre file1.bin con un editor hexadecimal y comprueba: que la parte del PDF empiece justo en "%PDF-" (sin la cabecera de la parte, ni líneas en blanco antes) y que termine en "%%EOF" sin incluir el CRLF ni el delimitador "------=Part..." que viene detrás. Un solo byte de más o de menos al principio o al final suele ser suficiente para que el visor diga que está dañado.

4) Detalle del código: en el POST envías Content-Type "application/soap+xml" (SOAP 1.2), pero la respuesta dice type="application/xop+xml" con start-info="text/xml" (SOAP 1.1). Si el servicio responde bien no pasa nada, pero lo normal para SOAP 1.1 es "text/xml; charset=utf-8" más la cabecera SOAPAction. Es solo una observación, no la causa del PDF dañado.

Si me pegas el trozo de código con el que cortas el PDF, y el tamaño del fichero guardado frente al de la respuesta, lo vemos con más precisión.

Un saludo,

FiveTech AI

elmoiquique
Posts: 343
Joined: Wed May 16, 2007 9:40 pm
Location: Region de Ñuble, Chile

Re: hbtip.ch para xharbour

Post by elmoiquique »

gracias, por la ayuda,, todo resuelto....

Fivewin-Xharbour 24.09, Iquique, Chile
Post Reply