jueves, 28 de abril de 2016
Convertir XML a Hash en Harbour ( Update IV )
Bueno, esto ya tiene más partes que el padrino. ;-)
Resulta que un amigo mío, me envia un XML de como leer unos atributos, que no encuentra la forma.
El XML de ejemplo, ver más abajo ,, que no es capaz de montar en cuestión;
<cfdi:Conceptos>
<cfdi:Concepto noIdentificacion="a" importe="1.123456" valorUnitario="1.123456" cantidad="0.0" descripcion="a" unidad="a">
<cfdi:InformacionAduanera aduana="3" numero="a" fecha="1967-08-13"/>
<cfdi:InformacionAduanera aduana="4" numero="a" fecha="1967-08-13"/>
</cfdi:Concepto>
Pues resulta, que <cfdi:InformacionAduanera/> nos muestra un bonito valor vacio.
Este parche , en la funcion NodeToHash( node ) ,soluciona el problema;
STATIC FUNCTION NodeToHash( node )
Local hNext
Local hHashChild := {=>}
Local hHash := {=>}
Local node2
WHILE node != NIL
IF mxmlGetType( node ) == MXML_ELEMENT
if HB_HHASKEY( hHash, mxmlGetElement( node ) )
if valtype( hHash[ mxmlGetElement( node ) ] ) <> "A"
hHash[ mxmlGetElement( node ) ] := mxmlGetOpaque( node )
else
// Es un array, por lo tanto, no lo tocamos
endif
else
hHash[ mxmlGetElement( node ) ] := mxmlGetOpaque( node )
endif
if empty( mxmlGetOpaque( node ) ) // Miramos dentro
hNext := mxmlWalkNext( node, node, MXML_DESCEND )
if hNext != NIL
hHashChild := NodeToHash( hNext )
// Correcion de Posible bug. Un elemento con espacios en blanco, deja descender un nivel!, cuando no debería!
// example <element> </element>
if hHashChild != NIL .and. !empty( hHashChild )
if empty( hHash[ mxmlGetElement( node ) ] )
hHash[ mxmlGetElement( node ) ] := {}
endif
if HB_MXMLGETATTRSCOUNT( node ) > 0
hHashChild[ mxmlGetElement( node ) + "@attr"] := HB_MXMLGETATTRS( node )
endif
AADD( hHash[ mxmlGetElement( node ) ], hHashChild )
endif
else
if HB_MXMLGETATTRSCOUNT( node ) > 0
if empty( hHash[ mxmlGetElement( node ) ] )
hHash[ mxmlGetElement( node ) ] := {}
endif
AADD( hHash[ mxmlGetElement( node ) ], HB_MXMLGETATTRS( node ) )
endif endif
else
if HB_MXMLGETATTRSCOUNT( node ) > 0
hHash[ mxmlGetElement( node ) + "@attr"] := HB_MXMLGETATTRS( node )
endif
endif
ENDIF
node := mxmlGetNextSibling( node )
END WHILE
return hHash
De paso, pongo aqui el ejemplo de como leer el nodo de los impuestos,
FUNCTION Test_xml( )
Local pRoot, hHash, hImpuestos, hPrecios, hVarios
pRoot := mxmlLoadString( NIL, hb_MemoRead( hb_dirBase() +"xml.xml" ), @type_cb() )
hHash := XMLtoHash( pRoot )
for each hImpuestos in hHash["cfdi:Comprobante"][1]["cfdi:Impuestos"][1]
do case
case hImpuestos:__enumKey == "cfdi:Retenciones"
hVarios := hImpuestos[1]["cfdi:Retencion"]
for each hPrecios in hVarios
Alert( "Importe Retencion:" + hPrecios["importe"] )
next
case hImpuestos:__enumKey == "cfdi:Traslados"
hVarios := hImpuestos[1]["cfdi:Traslado"]
for each hPrecios in hVarios
Alert( "Importe Traslados:" + hPrecios["importe"] )
next
end case
next
mxmlDelete( pRoot )
RETURN nil
Podemos ver los 2 elementos
Y el valor de uno de ellos
XML de ejemplo;
<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante MontoFolioFiscalOrig="1.123456" noCertificado="aaaaaaaaaaaaaaaaaaaa" formaDePago="String" motivoDescuento="a" metodoDePago="a" NumCtaPago="aaaa" certificado="String" sello="String" condicionesDePago="a" FolioFiscalOrig="String" descuento="1.123456" fecha="2001-12-17T09:30:47.0Z" subTotal="1.123456" SerieFolioFiscalOrig="String" LugarExpedicion="a" total="1.123456" Moneda="String" folio="a" serie="a" TipoCambio="String" tipoDeComprobante="ingreso" version="3.2" FechaFolioFiscalOrig="2001-12-17T09:30:47.0Z" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd" xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<cfdi:Emisor rfc="&&&&000000,," nombre="a">
<cfdi:DomicilioFiscal municipio="a" colonia="a" referencia="a" calle="a" noExterior="a" localidad="a" codigoPostal="aaaaa" noInterior="a" pais="a" estado="a"/>
<cfdi:ExpedidoEn municipio="a" colonia="a" referencia="a" calle="a" noExterior="a" localidad="a" codigoPostal="String" noInterior="a" pais="a" estado="a"/>
<cfdi:RegimenFiscal Regimen="a"/>
<cfdi:RegimenFiscal Regimen="a"/>
</cfdi:Emisor>
<cfdi:Receptor rfc="&&&&000000,," nombre="a">
<cfdi:Domicilio municipio="a" colonia="a" referencia="a" calle="a" noExterior="a" localidad="a" codigoPostal="String" noInterior="a" pais="a" estado="a"/>
</cfdi:Receptor>
<cfdi:Conceptos>
<cfdi:Concepto noIdentificacion="a" importe="1.123456" valorUnitario="1.123456" cantidad="0.0" descripcion="a" unidad="a">
<cfdi:InformacionAduanera aduana="3" numero="a" fecha="1967-08-13"/>
<cfdi:InformacionAduanera aduana="4" numero="a" fecha="1967-08-13"/>
</cfdi:Concepto>
</cfdi:Conceptos>
<cfdi:Impuestos totalImpuestosRetenidos="1.123456" totalImpuestosTrasladados="1.123456">
<cfdi:Retenciones>
<cfdi:Retencion importe="2.123456" impuesto="ISR"/>
<cfdi:Retencion importe="3.123456" impuesto="ISR"/>
</cfdi:Retenciones>
<cfdi:Traslados>
<cfdi:Traslado importe="4.123456" tasa="1.123456" impuesto="IVA"/>
<cfdi:Traslado importe="5.123456" tasa="1.123456" impuesto="IVA"/>
</cfdi:Traslados>
</cfdi:Impuestos>
<cfdi:Complemento/>
<cfdi:Addenda/>
</cfdi:Comprobante>
Suscribirse a:
Enviar comentarios (Atom)
Android y Git. Disponer del hash automáticamente.
Una de las cosas a las que estoy acostumbrado, es tener siempre en mi código, el hash/tag/versión del control de versiones que estoy usan...
-
Después de más de 2 años, sacrificando fin de semanas y tiempo libre, he podido pasar a una versión totalmente funcional. El Sofware es ca...
-
Os muestro un pequeño video de las posibilidades de Harbour funcioanando como un servidor Web. Dentro de /contrib/httpd, tenéis un serv...
-
Voy a publicar una serie de post sobre las funciones de threads que espero os sirva para comprender como podeis sacar provecho a ...
No hay comentarios:
Publicar un comentario