Sign in to follow this  
Followers 0
carabusu

XML recursive

3 posts in this topic

How can I recursive traverse an XML file to display all children in this order:

parent->child 1->child 1-1; parent->child1->child 1-2; parent->child2 ....

Thanks.

Share this post


Link to post
Share on other sites



I've tried something like this :

func traverse($xpath)
    msgbox(4096,"",$xpath)
    $nodesArray=_XMLGetChildNodes($xpath)
    
    if (IsArray($nodesArray) ) Then
            
            
            if Not($nodesArray[0]==0) Then
                for $i=1 to $nodesArray[0]
                    
                    $index=1
                    for $j=1 to $i-1
                    
                        if $nodesArray[$i]==$nodesArray[$j] Then $index=$index+1
                        
                    Next
                ;msgbox(4096,"",$i)
                ;msgbox(4096,"",$xpath & "/" & $nodesArray[$i] & "[" & $index & "]")
                ;msgbox(4096,"",_XMLGetPath($xpath &"/"&$nodesArray[$i]))
                    $areNodes=_XMLGetChildNodes($xpath & "/" & $nodesArray[$i])
                    if not($areNodes[0]==0) Then
                        traverse($xpath & "/" & $nodesArray[$i] & "[" & $index & "]")
                        
                    EndIf   
                Next;for $i=1 to $nodesArray[0]
                
            EndIf;if Not($nodesArray[0]==0) Then
        EndIf;if (IsArray($nodesArray) ) Then
    
EndFunc

but I have this error:

Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

if $nodesArray[$i]==$nodesArray[$j] Then $index=$index+1

if ^ ERROR

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Recursion is so ugly yet so elegant. This will dump all tag names and attributes. It doesn't dump values but that's easy to add. Good luck.

Code:

#include "..\_XMLDomWrapper.au3"

$sXMLFile = "config.xml"

$result = _XMLFileOpen($sXMLFile)
if $result = 0 then Exit

Traverse()

Func Traverse($path = "/", $depth = 0)
    
    Local $indent = ""
    Local $aKeys[1], $aValues[1] ;Arrays used for attributes
    
    ;If current level is greater than zero
    If $depth Then
        ;Add tabs for indentation
        For $Z = 1 to $depth
            $indent &= @TAB
        Next
    EndIf    

    $array = _XMLGetChildNodes($path)
    If $path = "/" Then $path = ""
    If IsArray($array) Then
        ConsoleWrite("!" & $indent & "Path: " & $path & @CRLF) ;Output indexed path in red
        For $X = 1 to $array[0]
            ConsoleWrite($indent & "[" & $X & "]: Element: " & $array[$X]) ;Output tag name
            _XMLGetAllAttrib($path & "/*[" & $X & "]",$aKeys, $aValues) ;Retrieve all attributes
            If NOT @ERROR Then
                ConsoleWrite(" - Attributes: ")
                For $Y = 0 to Ubound($aKeys)-1
                    ConsoleWrite($aKeys[$Y] & "=" & $aValues[$Y] & ", ") ;Output all attributes
                Next
            EndIf
            ConsoleWrite(@CRLF)
            
            Traverse($path & "/*[" & $X & "]", $depth+1)
        Next
        ConsoleWrite(@CRLF)
    EndIf
EndFunc

XML:

<?xml version="1.0"?>
 <menu>
   <folder name="Spyware" oscode="255">
     <folder name="Install" oscode="255">
       <folder name="Silent" oscode="255">
         <item name="Great-Grandchild item" target="PATH\TO\PROGRAM.EXE" oscode="255"/>
       </folder>
       <item name="Grandchild item" target="PATH\TO\PROGRAM.EXE" oscode="255"/>
     </folder>
     <item name="Child item" target="PATH\TO\PROGRAM.EXE" oscode="255"/>
     <folder name="TEST" oscode="255">
       <item name="Great-Grandchild item" target="PATH\TO\PROGRAM.EXE" oscode="255"/>
     </folder>
   </folder>
   <item name="Root item" target="PATH\TO\PROGRAM.EXE" oscode="255"/>
   <folder name="Antivirus" oscode="255">
     <item name="Another child item" target="PATH\TO\PROGRAM.EXE" oscode="255"/>
   </folder>
 </menu>

Output:

!Path: 
[1]: Element: menu
!   Path: /*[1]
    [1]: Element: folder - Attributes: name=Spyware, oscode=255, 
!       Path: /*[1]/*[1]
        [1]: Element: folder - Attributes: name=Install, oscode=255, 
!           Path: /*[1]/*[1]/*[1]
            [1]: Element: folder - Attributes: name=Silent, oscode=255, 
!               Path: /*[1]/*[1]/*[1]/*[1]
                [1]: Element: item - Attributes: name=Great-Grandchild item, target=PATH\TO\PROGRAM.EXE, oscode=255, 

            [2]: Element: item - Attributes: name=Grandchild item, target=PATH\TO\PROGRAM.EXE, oscode=255, 

        [2]: Element: item - Attributes: name=Child item, target=PATH\TO\PROGRAM.EXE, oscode=255, 
        [3]: Element: folder - Attributes: name=TEST, oscode=255, 
!           Path: /*[1]/*[1]/*[3]
            [1]: Element: item - Attributes: name=Great-Grandchild item, target=PATH\TO\PROGRAM.EXE, oscode=255, 


    [2]: Element: item - Attributes: name=Root item, target=PATH\TO\PROGRAM.EXE, oscode=255, 
    [3]: Element: folder - Attributes: name=Antivirus, oscode=255, 
!       Path: /*[1]/*[3]
        [1]: Element: item - Attributes: name=Another child item, target=PATH\TO\PROGRAM.EXE, oscode=255,
Edited by weaponx

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0