MarioDava wrote:Ok Rafael, te comento, tambien estoy usando xHarbour 00.99.70, pero me puedes indicar el nombre de la librerái donde se encuentran estas clases.
Saludos,
thefull wrote:MarioDava wrote:Thefull, de hecho si vi tus articulos, e hice las pruebas pero no me funciono, primero no supe cual era la libreria o si era un prg con la clase, que include se necesitaba, etc.
De hecho tampoco me funciono la clase XMLRead, así que me ire con las sugerencia de Miguel.
Pero agradezco la atención.
Saludos,
Pues la libreria TIP creo que es la que contiene el tema de internet, XML, etc.
De todas maneras, tienes que poner el #include "hbxml.ch"m, ademas
de compilar con la libreria pcrepos, soporte de expresiones regulares,
pero no estoy seguro de ello, puesto que pueden que hayan cambiado
alguna parte de xHarbour que no se comporte como deberia...
Me parece una burrada el codigo que habeis puesto, pues es inmantenible a la larga, solamente sirve para salir del paso , pero no para abordar el problema.
La solucion mucho más potente , en todos los sentidos, es usar las clases
de Giancarlo, que realizó para xHarbour, ahora estan tambien pasandolas a Harbour.
Te voy a poner un ejemplo practico, para que puedes ver realmente como funciona;
Ejemplo:
- Code: Select all Expand view RUN
#include "fileio.ch"
#include "hbxml.ch"
PROCEDURE Main( cFileName )
hFile := FOpen( cFileName )
If hFile = -1
Error_Msg( cFileName, "No se pudo abrir el fichero" + cFileName )
return
endif
oXmlDoc := TXmlDocument():New( hFile )
if oXmlDoc:nStatus != HBXML_STATUS_OK
cError := "Error While Processing File: " + AllTrim( Str( oxmlDoc:nLine ) ) + " # "+;
"Error: " + HB_XmlErrorDesc( oxmlDoc:nError ) + " # " +;
"Tag Error on tag: " + oxmlDoc:oErrorNode:cName + " # " +;
"Tag Begin on line: " + AllTrim( Str( oxmlDoc:oErrorNode:nBeginLine ) )
Error_Msg( cFileName, cError )
QUIT
endif
if( oNodo := oXmlDoc:FindFirst( "PETICION", "id", "CONSULTA_EMPRESA" ) ) != NIL )
Consulta_Empresa( oNodo, cFileName )
endif
fClose( hFile )
RETURN
*******************************************************************************
*******************************************************************************
STATIC FUNCTION Consulta_Empresa( oNodo, cFile )
Local oIter, oNodeChild , oNode, oIterDia, oNodeDia, oNodeDet
Local oNodeHab
Local nCodigo , cNombre
Local oDoc, oRes, oNode_Empresa, oUnidad, oDbf
Local cPath, cFileName
If !open( "AGENCIAS" )
Error_Msg( cFile, "NO SE PUDO ABRIR AGENCIAS", "CONSULTA_EMPRESA" )
Return NIL
Endif
DATABASE oDbf
oDbf:SetBuffer( .F. )
// Buscando codigo
oIter := TXMLIteratorScan():New( oNodo )
oNode := oIter:Find( "PARAM", "id", "codigo" )
nCodigo := oNode:GetAttribute("valor")
oNode := oNode:oNext // El siguiente en el nodo es el nombre
//cNombre := oNode:GetAttribute("valor")
cNombre := oNode:oChild:cData // Para VALORES CDATA
oDoc := TXmlDocument():New() // Creacion del documento respuesta....
oDoc:oRoot:AddBelow( TxmlNode():New( HBXML_TYPE_PI,'xml' , , 'version="1.0" encoding="iso-8859-1"' ) )
oRes := TxmlNode():New( HBXML_TYPE_TAG, "RESPUESTA" )
oRes:SetAttribute( "id", "CONSULTA_EMPRESA" )
oRes:SetAttribute( "res", "OK" )
oDoc:oRoot:AddBelow( oRes )
oNode_Empresa := TxmlNode():New( HBXML_TYPE_TAG, "LEMPRESAS" )
IF !Empty( nCodigo ) // Pasamos codigo, buscamos por codigo
nCodigo = VAL( nCodigo )
IF DbSeek( nCodigo )
oUnidad := SAVEAGE2XML( oDbf )
oNode_Empresa:AddBelow( oUnidad )
ENDIF
ELSE // El codigo esta vacio, buscamos por nombre
IF !Empty( cNombre )
oDbf:SetOrder( 2 )
IF DbSeek( cNombre )
While !oDbf:Eof()
IF cNombre = Substr( oDbf:Ag_Nom, 1, Len( cNombre ) )
oUnidad := SAVEAGE2XML( oDbf )
oNode_Empresa:AddBelow( oUnidad )
ELSE
EXIT
ENDIF
oDbf:Skip()
SysRefresh()
end while
ENDIF
ENDIF
ENDIF
oDbf:Close()
*oDoc:oRoot:AddBelow( oNode_Empresa )
oRes:AddBelow( oNode_Empresa )
cPath := cFilePath( cFile )
if cPath == ""
cPath := ""
endif
cFileName := Name_File( cFile )
hFile := FCreate( cPath + cFileName + ".RES" )
If hFile != -1
oDoc:Write( hFile, HBXML_STYLE_INDENT + HBXML_STYLE_THREESPACES )
FClose( hFile )
Endif
SysRefresh()
RETURN NIL
*******************************************************************************
*******************************************************************************
STATIC FUNCTION SAVEAGE2XML( oDbf )
Local oNodo, oNombre, oDirec, oCData, oPobla, oPais, oProv, oCodigo
oNodo := TxmlNode():New( HBXML_TYPE_TAG, "EMPRESA" )
oCodigo := TxmlNode():New( HBXML_TYPE_TAG, "PARAM" )
oCodigo:SetAttribute( "id", "codigo" )
oCodigo:SetAttribute( "valor", alltrim( str( oDbf:Ag_Codi ) ) )
oNodo:AddBelow( oCodigo )
// Metemos Codigo.
*oNodo:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, "codigo", , alltrim( str( oDbf:Ag_Codi ) ) ) )
// Nombre
oNombre := TxmlNode():New( HBXML_TYPE_TAG, "PARAM" )
oNombre:SetAttribute( "id", "nombre" )
// Atencion.. si activamos esta linea, crearia <nombre>[[CDATA]]</nombre>
// oNombre := TxmlNode():New( HBXML_TYPE_TAG, "nombre" )
oCData := TxmlNode():New( HBXML_TYPE_CDATA )
oCData:cData := OemToAnsi( Alltrim( oDbf:Ag_Nom ) )
oNombre:AddBelow( oCData )
oNodo:AddBelow( oNombre )
// Direccion
oDirec := TxmlNode():New( HBXML_TYPE_TAG, "PARAM" )
oDirec:SetAttribute( "id", "direccion" )
oCData := TxmlNode():New( HBXML_TYPE_CDATA )
oCData:cData := OemToAnsi( Alltrim( oDbf:Ag_direcci ) )
oDirec:AddBelow( oCData )
oNodo:AddBelow( oDirec )
// Poblacion
oPobla := TxmlNode():New( HBXML_TYPE_TAG, "PARAM" )
oPobla:SetAttribute( "id", "poblacion" )
oCData := TxmlNode():New( HBXML_TYPE_CDATA )
oCData:cData := OemToAnsi( Alltrim( oDbf:Ag_poblaci ) )
oPobla:AddBelow( oCData )
oNodo:AddBelow( oPobla )
// Provincia
oProv := TxmlNode():New( HBXML_TYPE_TAG, "PARAM" )
oProv:SetAttribute( "id","provincia" )
oCData := TxmlNode():New( HBXML_TYPE_CDATA )
oCData:cData := OemToAnsi( Alltrim( oDbf:Ag_PoblaC2 ) )
oProv:AddBelow( oCData )
oNodo:AddBelow( oProv )
// Pais
oPais := TxmlNode():New( HBXML_TYPE_TAG, "PARAM" )
oPais:SetAttribute( "id","pais" )
oCData := TxmlNode():New( HBXML_TYPE_CDATA )
oCData:cData := OemToAnsi( Alltrim( oDbf:Ag_Pais ) )
oPais:AddBelow( oCData )
oNodo:AddBelow( oPais )
RETURN oNodo
Para entenderlo , te pongo la definicion del XML, con su explicacion, para
que puedas hacerte una idea.
******************************************************************************
PETICION DE CONSULTA PARA EMPRESAS
******************************************************************************
"codigo"
Si el valor de codigo es diferente que vacio, devolverá en la respuesta
solamente la empresa/agencia de ese codigo.
"nombre"
Si se da nombre, y el valor de codigo esta vacio, devolverá una lista
conteniendo los registros que cumplan solamente el contenido inicial del
nombre, es decir, si el valor es "EL CORTE", se seleccionaran TODOS los que
empiezan por "EL CORTE".
<?xml version="1.0" encoding="iso-8859-1"?>
<PETICION id="CONSULTA_EMPRESA">
<LPARAMS>
<PARAM id="codigo" valor="xxx"/>
<PARAM id="nombre"> <![CDATA[A & B]]> </PARAM>
</LPARAMS>
******************************************************************************
RESPUESTA PARA CONSULTA DE EMPRESA
******************************************************************************
El fichero generado sera igual al que hemos pasado , pero con la extension
.RES. El fichero resultante se creará donde este el fichero pasado.
El contenido de [[CDATA]] se establece para que el parseador de XML no tenga
en cuenta el contenido.
<?xml version="1.0" encoding="iso-8859-1"?>
<RESPUESTA id="CONSULTA_EMPRESA" res="OK">
<LEMPRESAS>
<EMPRESA>
<PARAM id="codigo" valor=""/>
<PARAM id="nombre"> <![CDATA[]]> </PARAM>
<PARAM id="direccion"> <![CDATA[]]> </PARAM>
<PARAM id="poblacion"> <![CDATA[]]> </PARAM>
<PARAM id="provincia"> <![CDATA[]]> </PARAM>
<PARAM id="pais"> <![CDATA[]]> </PARAM>
</EMPRESA>
</LEMPRESAS>
</RESPUESTA>
res="OK" retorna siempre que se a realizado con exito.
De lo contrario, devuelve res="ERROR" y descripcion="Texto del error",
por ejemplo:
<?xml version="1.0" encoding="iso-8859-1"?>
<RESPUESTA id="CONSULTA_EMPRESA" res="ERROR" descripcion="No se puede...">
Es decir, el ejemplo que te he puesto, es capaz de leer un XML de entrada
para ocasionarte una XML de salida, 2x1
Sinceramente, esto que te he puesto es MUCHISIMO más potente de usar.
Cualquier duda, por aqui.