Jump to content
Fivewin Brasil

Convertir XML a Hash em Harbour


kapiaba

Recommended Posts


/*
XML

<?xml version="1.0" encoding="utf-8"?>
<data>
<node1></node1>
<node2>val2</node2>
<node3>val3</node3>
<group>
<node1>val4</node1>
<node2>val5</node2>
<node3>val6</node3>
</group>
<group>
<node1>val24</node1>
<node2>val25</node2>
<node3>val26</node3>
<extras>
<node1>Extra_val24</node1>
<node2>Extra_val25</node2>
<node3>Extra_val26</node3>
</extras>
</group>
<node7>val7</node7>
<node8>val8</node8>
</data>
*/

#include "FiveWin.ch"

*PRG

FUNCTION Test( file )

Local pRoot, hHash

pRoot := mxmlLoadString( NIL, hb_MemoRead( file ), @type_cb() )
hHash := XMLtoHash( pRoot, "data" )

// Podemos acceder fácilmente ;
?? hHash["node2"] // Muestra val2
?? hHash["group"][1]["node1"] // Muestra val4
?? hHash["group"][2]["extras"][1]["node1"] // Muestra Extra_val24

mxmlDelete( pRoot )

RETURN nil

STATIC FUNCTION type_cb( node ) ; RETURN MXML_TEXT


// ---------------------------------------------------------------------------//
FUNCTION XMLtoHash( pRoot, cElement )
Local pNode, hNext
Local Map := {=>}

if empty( cElement )
pNode := pRoot
else
pNode := mxmlFindElement( pRoot, pRoot, cElement, NIL, NIL, MXML_DESCEND )
endif

IF Empty( pNode )
RETURN Map
ENDIF

hNext := mxmlWalkNext( pNode, pNode, MXML_DESCEND )
Map := NodeToHash( hNext )

return Map
// ---------------------------------------------------------------------------//
STATIC FUNCTION NodeToHash( node )
Local wt := 0
Local hNext
Local hHashChild := {=>}
Local hHash := {=>}

WHILE node != NIL

IF mxmlGetType( node ) == MXML_ELEMENT

if HB_HHASKEY( hHash, mxmlGetElement( node ) )
if valtype( hHash[ mxmlGetElement( node ) ] ) <> "A"
hHash[ mxmlGetElement( node ) ] := mxmlGetText( node,@wt )
else
// Es un array, por lo tanto, no lo tocamos
endif
else
hHash[ mxmlGetElement( node ) ] := mxmlGetText( node,@wt )
endif

if empty( mxmlGetText( node,@wt ) ) // Miramos dentro
hNext := mxmlWalkNext( node, node, MXML_DESCEND )
if hNext != NIL
if empty( hHash[ mxmlGetElement( node ) ] )
hHash[ mxmlGetElement( node ) ] := {}
endif
hHashChild := NodeToHash( hNext )
if hHashChild != NIL
AADD( hHash[ mxmlGetElement( node ) ], hHashChild )
endif
endif
endif
ENDIF

node := mxmlGetNextSibling( node )

END WHILE

RETURN hHash


Link to comment
Share on other sites

Alguém pode testar? Não consigo fazer funcionar...




Application
===========
Path and name: C:\FWH1505\samples\XMLHASH.exe (32 bits)
Size: 3,095,552 bytes
Compiler version: Harbour 3.2.0dev (r1501292255)
FiveWin Version: FWH 15.05
Windows version: 6.1, Build 7601 Service Pack 1

Time from start: 0 hours 0 mins 0 secs
Error occurred at: 11/25/15, 10:29:31
Error description: Error BASE/3012 Argument error: MXMLFINDELEMENT
Args:
[ 1] = U
[ 2] = U
[ 3] = C data
[ 4] = U
[ 5] = U
[ 6] = N 1

Stack Calls
===========
Called from: => MXMLFINDELEMENT( 0 )
Called from: XMLHASH.prg => XMLTOHASH( 49 )
Called from: XMLHASH.prg => TEST( 28 )
Called from: XMLHASH.prg => MAIN( 15 )

Link to comment
Share on other sites

Código:

#Include "FiveWin.ch"
#Include "hbmxml.ch"
#include "common.ch"
#include "simpleio.ch"
 
FUNCTION Main()
 
   LOCAL cFile
   LOCAL File
 
   File := MemoRead( "TESTE.XML" )
 
   //? File
 
   cFile := TEST( File )
 
   // ? cFile
 
RETURN NIL
 
*PRG
 
FUNCTION Test( file )
 
  Local pRoot, hHash
 
  pRoot :=   mxmlLoadString( NIL, hb_MemoRead( file ),  @type_cb() )
  hHash := XMLtoHash( pRoot, "data" )
  
  // Podemos acceder fácilmente ;
  ?  hHash["node2"]  // Muestra val2
  ?  hHash["group"][1]["node1"] // Muestra val4
  ?  hHash["group"][2]["extras"][1]["node1"] // Muestra Extra_val24
 
  mxmlDelete( pRoot )
 
RETURN nil
 
STATIC FUNCTION type_cb( node ) ;  RETURN MXML_TEXT
 
// ---------------------------------------------------------------------------//
FUNCTION XMLtoHash( pRoot, cElement )
   Local pNode, hNext
   Local Map := {=>}
 
   if empty( cElement )
      pNode := pRoot
   else   
      pNode := mxmlFindElement( pRoot, pRoot, cElement, NIL, NIL, MXML_DESCEND )
   endif
      
   IF Empty( pNode )
      RETURN Map
   ENDIF
 
   hNext := mxmlWalkNext( pNode, pNode, MXML_DESCEND )
   Map :=  NodeToHash( hNext ) 
 
return Map
 
// ---------------------------------------------------------------------------//
STATIC FUNCTION NodeToHash( node  )
 
   Local wt := 0
   Local hNext
   Local hHashChild := {=>}
   Local hHash := {=>} 
 
   WHILE node != NIL
          
         IF mxmlGetType( node ) == MXML_ELEMENT
 
            if HB_HHASKEY( hHash, mxmlGetElement( node ) )
               if valtype( hHash[ mxmlGetElement( node ) ] ) <> "A"
                  hHash[ mxmlGetElement( node ) ] := mxmlGetText( node,@wt )
               else
                 // Es un array, por lo tanto, no lo tocamos
               endif   
            else                   
               hHash[ mxmlGetElement( node ) ] := mxmlGetText( node,@wt )
            endif     
            
            if empty( mxmlGetText( node,@wt ) ) // Miramos dentro
               hNext := mxmlWalkNext( node, node, MXML_DESCEND )   
               if hNext != NIL
                  if empty( hHash[ mxmlGetElement( node ) ]  )
                     hHash[ mxmlGetElement( node ) ] := {}
                  endif   
                   hHashChild :=  NodeToHash( hNext  )
                   if hHashChild != NIL
                      AADD( hHash[ mxmlGetElement( node ) ], hHashChild )
                   endif   
               endif   
            endif
         ENDIF    
 
         node := mxmlGetNextSibling( node ) 
                     
   END WHILE
 
RETURN hHash
 
/*
XML
 
<?xml version="1.0" encoding="utf-8"?>
<data>
    <node1></node1>
    <node2>val2</node2>
    <node3>val3</node3>
    <group>
        <node1>val4</node1>
        <node2>val5</node2>
        <node3>val6</node3>
    </group>
    <group>
        <node1>val24</node1>
        <node2>val25</node2>
        <node3>val26</node3>
      <extras>
            <node1>Extra_val24</node1>
            <node2>Extra_val25</node2>
            <node3>Extra_val26</node3>
        </extras>
    </group>
    <node7>val7</node7>
    <node8>val8</node8>
</data>
*/
Link to comment
Share on other sites

Resuelto,


gracias, Rafa Carmona.



#Include "FiveWin.ch"
#Include "hbmxml.ch"

FUNCTION Main()

LOCAL cFile := "TESTE.XML"

TEST( cFile )

RETURN NIL

*PRG

FUNCTION Test( file )

Local pRoot, hHash

pRoot := mxmlLoadString( NIL, hb_MemoRead( file ), @type_cb() )
hHash := XMLtoHash( pRoot, "data" )

// Podemos acceder fácilmente ;
? hHash["node2"] // Muestra val2

? hHash["group"][1]["node1"] // Muestra val4

? hHash["group"][2]["extras"][1]["node1"] // Muestra Extra_val24

mxmlDelete( pRoot )

RETURN nil

STATIC FUNCTION type_cb( node ) ; RETURN MXML_TEXT

// ---------------------------------------------------------------------------//
FUNCTION XMLtoHash( pRoot, cElement )
Local pNode, hNext
Local Map := {=>}

if empty( cElement )
pNode := pRoot
else
pNode := mxmlFindElement( pRoot, pRoot, cElement, NIL, NIL, MXML_DESCEND )
endif

IF Empty( pNode )
RETURN Map
ENDIF

hNext := mxmlWalkNext( pNode, pNode, MXML_DESCEND )
Map := NodeToHash( hNext )

return Map

// ---------------------------------------------------------------------------//
STATIC FUNCTION NodeToHash( node )

Local wt := 0
Local hNext
Local hHashChild := {=>}
Local hHash := {=>}

WHILE node != NIL

IF mxmlGetType( node ) == MXML_ELEMENT

if HB_HHASKEY( hHash, mxmlGetElement( node ) )
if valtype( hHash[ mxmlGetElement( node ) ] ) <> "A"
hHash[ mxmlGetElement( node ) ] := mxmlGetText( node,@wt )
else
// Es un array, por lo tanto, no lo tocamos
endif
else
hHash[ mxmlGetElement( node ) ] := mxmlGetText( node,@wt )
endif

if empty( mxmlGetText( node,@wt ) ) // Miramos dentro
hNext := mxmlWalkNext( node, node, MXML_DESCEND )
if hNext != NIL
if empty( hHash[ mxmlGetElement( node ) ] )
hHash[ mxmlGetElement( node ) ] := {}
endif
hHashChild := NodeToHash( hNext )
if hHashChild != NIL
AADD( hHash[ mxmlGetElement( node ) ], hHashChild )
endif
endif
endif
ENDIF

node := mxmlGetNextSibling( node )

END WHILE

RETURN hHash

/*
XML

<?xml version="1.0" encoding="utf-8"?>
<data>
<node1></node1>
<node2>val2</node2>
<node3>val3</node3>
<group>
<node1>val4</node1>
<node2>val5</node2>
<node3>val6</node3>
</group>
<group>
<node1>val24</node1>
<node2>val25</node2>
<node3>val26</node3>
<extras>
<node1>Extra_val24</node1>
<node2>Extra_val25</node2>
<node3>Extra_val26</node3>
</extras>
</group>
<node7>val7</node7>
<node8>val8</node8>
</data>
*/


Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...