martes, 25 de abril de 2017

Convertir XML a Hash en Harbour ( Update V )


Bueno, pues de probar con un montón de XML diferentes , me encuentro que uno de tantos cientos probamos, no lo hace como se esperaba.

Simplificando y reduciendo el XML para ver donde está el problema;


<?xml version="1.0" encoding="utf-8"?>
 <UpdateCustomerProfile> 
     <request> 
          <Id>001</Id> 
          <ReservationNumber>123456</ReservationNumber>
          <Email> 
                 <string>uno@moo.com</string>
                 <string>dos@moo.com</string>
          </Email>
     </request>
</UpdateCustomerProfile>

Al pasar por la función XMTOHASH( ), el efecto que ocurre es que solo tendremos el valor
de string, con el ultimo valor, dos@moo.com

¿ Y porque ocurre esto ? 

Ocurre simplemente, porque se ha llegado al final , y no tiene hijos,  y como el node se llama igual, lo que hace la función es volver asignarle a hash con la clave string ,que si tenemos, con el nuevo valor.
La consecuencia es que no podemos tener los valores de ninguna de las maneras.


Como podéis observa en la imagen, el hash solo podemos tener el último valor del string.

Bien, ¿ como solucionarlo  ? 

Sencillamente, vamos a crear un array de childs, que en caso que  la clave sea igual a lo que tengo, se guardará posteriormente para remplazar el valor que hay por este array child.
En casos como este, tendremos que preguntar si el valor del hash["string"] de que tipo es,
CARACTER o ARRAY, para procesar posteriormente el hash.

Aquí el código final, en color azul, el parche aplicar a la funcion recursiva NodeToHash();


STATIC FUNCTION NodeToHash( node ) Local hNext Local hHashChild := {=>} Local hHash := {=>} Local node2 Local hChild := {=>}, cKey /* hChild es un hash, que tiene la key en el cual vamos añadiendo
en el array los elementos iguales. */ WHILE node != NIL IF mxmlGetType( node ) == MXML_ELEMENT if HB_HHASKEY( hHash, mxmlGetElement( node ) ) if valtype( hHash[ mxmlGetElement( node ) ] ) <> "A" if empty( hChild ) hChild[ mxmlGetElement( node ) ] := {} aadd( hChild[ mxmlGetElement( node ) ] , hHash[ mxmlGetElement( node ) ] ) aadd( hChild[ mxmlGetElement( node ) ] , mxmlGetOpaque( node ) ) // Mas el valor del nuevo nodo else aadd( hChild[ mxmlGetElement( node ) ], mxmlGetOpaque( node ) ) // Mas el valor del nuevo nodo endif 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
 // En caso que el array tenga mas de un elemento, tenemos que alimentarlo
// con el array de su clave.
   if !empty( hChild )
      cKey := hb_HKeyAt( hChild, 1) 
      hHash[ cKey ] := hChild[ cKey ]
   endif   
return hHash

Como consecuencia de este trozo de código ,  ahora tenemos en un array los elementos disponibles;

Si si, eso esta muy bien, pero algo como esto; ( Incrédulos ;-)  )


<?xml version="1.0" encoding="utf-8"?>
 <UpdateCustomerProfile> 
     <request> 
          <Id>001</Id> 
          <ReservationNumber>123456</ReservationNumber>
          <Email> 
                 <string>uno@moo.com</string>
                 <string>dos@moo.com</string>
                 <string>
                      <string>compicado@es.es</string>
                 </string>
          </Email>
     </request>
</UpdateCustomerProfile>




Disfruten del parche! 

miércoles, 22 de marzo de 2017

Se rompió la BIOS.

Estaba yo dispuesto a pasar un fin de semana de relax en el ordenador , cuando de repente, lo que nunca me había pasado, y mira que se me han roto casi TODO lo que cae en mis manos ;





ACOJONADO!!! Al menos se recupero con el Backup

¿ La consecuencia de esto ? Pues el efecto lateral en Linux /Linux Ubuntu es que dejaron de funcionar los USB-2, solo los UBS-3 iban, pero lo pero de todo ello, es que las conexiones Bluetooh, Red, Impresoras, etc dejaron de funcionar.

Rebuscando por Internet, creo que hace tiempo ya lo realice en prueba y error, encontré que la placa
GIGABYTE GA-990FXA-UD3  hay que activar en la BIOS,  IOMMU to "Enabled". !!!!


Ahora ya funciona RED y USB.

"La IOMMU es una unidad de gestión de la memoria, similar a la MMU, que se sitúa entre un bus de E/S y la memoria." Pues cony, DEJALO ACTIVADO POR DEFECTO!!!! ;-)