PureBasic
;
; ------------------------------------------------------------
;
;   PureBasic - Xml
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

#Window     = 0
#TreeGadget = 0
#XML        = 0

; Эта процедура заполняет наш TreeGadget, добавляет текущий узел 
; и затем исследует все дочерние узлы путем рекурсивного вызова самой себя.
;
Procedure FillTree(*CurrentNode, CurrentSublevel)

  ; Игнорирует все, кроме обычных узлов. См. Руководство по 
  ; XMLNodeType() для объяснения других типов узлов.
  ;
  If XMLNodeType(*CurrentNode) = #PB_XML_Normal
  
    ; Добавляет этот узел в дерево. Добавляет имя и атрибуты
    ;
    Text$ = GetXMLNodeName(*CurrentNode) + " (Attributes: "
        
    If ExamineXMLAttributes(*CurrentNode)
      While NextXMLAttribute(*CurrentNode)
        Text$ + XMLAttributeName(*CurrentNode) + "=" + Chr(34) + XMLAttributeValue(*CurrentNode) + Chr(34) + " "
      Wend
    EndIf
    
    Text$ + ")"
    
    AddGadgetItem(#TreeGadget, -1, Text$, 0, CurrentSublevel)
        
        
    ; Теперь получим первый дочерний узел (если есть)
    ;    
    *ChildNode = ChildXMLNode(*CurrentNode)
    
    ; Цикл через все доступные дочерние узлы и снова вызовите эту процедуру
    ;
    While *ChildNode <> 0
      FillTree(*ChildNode, CurrentSublevel + 1)      
      *ChildNode = NextXMLNode(*ChildNode)
    Wend        
  
  EndIf

EndProcedure

FileName$ = OpenFileRequester("Choose XML file...", "", "XML files (*.xml)|*.xml|All files (*.*)|*.*", 0)
If FileName$ <> ""

  If LoadXML(#XML, FileName$)

    ; Заметка: 
    ;   Выполнение LoadXML() будет успешным, если файл может быть прочитан. Это 
    ;   не означает, что в XML не было ошибок. Чтобы проверить это, можно 
    ;   использовать XMLStatus().
    ;
    ; Отобразит сообщение об ошибке, если произошла ошибка разметки
    ;
    If XMLStatus(#XML) <> #PB_XML_Success
      Message$ = "Error in the XML file:" + Chr(13)
      Message$ + "Message: " + XMLError(#XML) + Chr(13)
      Message$ + "Line: " + Str(XMLErrorLine(#XML)) + "   Character: " + Str(XMLErrorPosition(#XML))
      MessageRequester("Ошибка", Message$)
    EndIf
    
    ; Заметка:
    ;   Даже если в XML произошла ошибка, все узлы разобранные до ошибки будут доступны,
    ;   поэтому откройте окно и покажите дерево в любом случае.
    ;
    If OpenWindow(#Window, 0, 0, 500, 500, "XML Example", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
      TreeGadget(#TreeGadget, 10, 10, 480, 480)
      
      ; Получить основной узел XML и вызвать его с помощью процедуры FillTree()
      ;
      *MainNode = MainXMLNode(#XML)      
      If *MainNode
        FillTree(*MainNode, 0)
      EndIf
      
      ; Разверните все узлы для более приятного просмотра
      ;
      For i = 0 To CountGadgetItems(#TreeGadget) - 1
        SetGadgetItemState(#TreeGadget, i, #PB_Tree_Expanded)
      Next i
      
      ; Ожидает закрытия окна.
      ;
      Repeat
        Event = WaitWindowEvent()
      Until Event = #PB_Event_CloseWindow
    EndIf
        
  Else
    MessageRequester("Ошибка", "The file cannot be opened.")
  EndIf

EndIf