Ahora que hemos publicado una forma simple de analizar un fichero XML, ahora podemos implementarle un visor GUI:
viewtopic.php?f=3&t=25741
xmltree.prg

test.xml
viewtopic.php?f=3&t=25741
xmltree.prg
#include "FiveWin.ch"
#include "Splitter.ch"
static oSplit1, oSplit2, oLbxDatas, oLbxMethods
//----------------------------------------------------------------------------//
function Main()
聽 聽local oWnd
聽 聽DEFINE WINDOW oWnd TITLE "XML viewer" ;
聽 聽 聽 MENU BuildMenu()
聽 聽ACTIVATE WINDOW oWnd ;
聽 聽 聽 ON INIT BuildTree( oWnd ) ;
聽 聽 聽 ON RESIZE ( If( oSplit1 != nil, oSplit1:AdjLeft(),),;
聽 聽 聽 聽 聽 聽 聽 聽 聽 If( oSplit2 != nil, oSplit2:AdjRight(),) )
return nil
//----------------------------------------------------------------------------//
function BuildMenu()
聽 聽local oMenu
聽 聽MENU oMenu
聽 聽 聽 MENUITEM "About" ACTION MsgAbout( "XML Viewer", "FiveTech Software" )
聽 聽ENDMENU
return oMenu
//----------------------------------------------------------------------------//
function BuildTree( oWnd )
聽 聽local oTree := TTreeView():New( 0, 0, oWnd )
聽 聽local oClass, cData, cMethod
聽 聽local hFile, oXmlDoc, oXmlIter, oTagActual
聽 聽local oTagLast, aRoots := {}
聽 聽oTree:nWidth = 180
聽 聽// oTree:SetImageList( oImageList )
聽 聽oTree:Expand()
聽 聽@ 0, 186 LISTBOX oLbxDatas VAR cData ITEMS { "one", "two", "three" } ;
聽 聽 聽 SIZE 200, 200 PIXEL OF oWnd
聽 聽@ 0, 391 LISTBOX oLbxMethods VAR cMethod ITEMS { "one", "two", "three" } ;
聽 聽 聽 SIZE 200, 200 PIXEL OF oWnd
聽 聽@ 0, 181 SPLITTER oSplit1 ;
聽 聽 聽 VERTICAL ;
聽 聽 聽 PREVIOUS CONTROLS oTree ;
聽 聽 聽 HINDS CONTROLS oLbxDatas ;
聽 聽 聽 LEFT MARGIN 150 ; 聽
聽 聽 聽 RIGHT MARGIN oSplit2:nLast + 100 ;
聽 聽 聽 SIZE 4, 300 聽PIXEL ;
聽 聽 聽 OF oWnd STYLE
聽 聽@ 0, 386 SPLITTER oSplit2 ;
聽 聽 聽 VERTICAL ;
聽 聽 聽 PREVIOUS CONTROLS oLbxDatas ;
聽 聽 聽 HINDS CONTROLS oLbxMethods ;
聽 聽 聽 LEFT MARGIN oSplit1:nFirst + 120 ;
聽 聽 聽 RIGHT MARGIN 80 ;
聽 聽 聽 SIZE 4, 300 PIXEL ;
聽 聽 聽 OF oWnd STYLE
聽 聽hFile 聽 聽= FOpen( "test.xml" )
聽 聽oXmlDoc 聽= TXmlDocument():New( hFile )
聽 聽oXmlIter = TXmlIterator():New( oXmlDoc:oRoot )
聽 聽AAdd( aRoots, oTree )
聽 聽while ( oTagActual := oXmlIter:Next() ) != nil
聽 聽 聽 // aRoots[ oTagActual:Depth() ]:Add( oTagActual:cName )
聽 聽 聽 // oRoot:Add( oTagActual:cName )
聽 聽 聽 if oTagLast != nil
聽 聽 聽 聽 聽if oTagLast:Depth() < oTagActual:Depth()
聽 聽 聽 聽 聽 聽 ASize( aRoots, Len( aRoots ) + 1 )
聽 聽 聽 聽 聽 聽 aRoots[ oTagActual:Depth() ] = aRoots[ oTagActual:Depth() - 1 ]:Add( oTagActual:cName )
聽 聽 聽 聽 聽 聽 // MsgInfo( oTagActual:cName + ", " + "open node", oTagActual:Depth() )
聽 聽 聽 聽 聽endif
聽 聽 聽 聽 聽if oTagLast:Depth() > oTagActual:Depth()
聽 聽 聽 聽 聽 聽 aRoots[ oTagActual:Depth() - 1 ]:Add( oTagActual:cName )
聽 聽 聽 聽 聽 聽 // MsgInfo( oTagActual:cName + ", " + "close node", oTagActual:Depth() )
聽 聽 聽 聽 聽endif
聽 聽 聽 聽 聽if oTagLast:Depth() == oTagActual:Depth()
聽 聽 聽 聽 聽 聽 aRoots[ Max( oTagLast:Depth() - 1, 1 ) ]:Add( oTagActual:cName )
聽 聽 聽 聽 聽 聽 // MsgInfo( oTagActual:cName + ", " + "keeps node", oTagActual:Depth() )
聽 聽 聽 聽 聽endif
聽 聽 聽 else
聽 聽 聽 聽 聽AAdd( aRoots, oTree:Add( oTagActual:cName ) )
聽 聽 聽 聽 聽// MsgInfo( oTagActual:cName + ", " + "starts", oTagActual:Depth() ) 聽
聽 聽 聽 endif
聽 聽 聽 oTagLast = oTagActual
聽 聽end 聽
聽
聽 聽// HEval( oTagActual:aAttributes, { | cKey, cValue | MsgInfo( cKey, cValue ) } )
聽 聽FClose( hFile )
聽 聽// oTree:bChanged = { || ShowClassInfo( oTree ) }
return nil
//----------------------------------------------------------------------------//
test.xml
<xml>
<one>
<name>FiveWin</name>
<company>FiveTech Software</company>
</one>
<two attribute1="att1" attribute2="att2">
</two>
<three>
</three>
</xml>


