Seite 1 von 1

Wie Ende des xml auslesen feststellen ?

Verfasst: 11.09.2016 16:34
von schleicher
Ich bräuchte eine Rückmeldung , wenn das xml verarbeiten zu Ende ist. Habe leider selbst noch keine Lösung gefunden. Kann mir das mal jemand erklären, wie man das macht ?

Code: Alles auswählen

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

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

; This procedure fills our TreeGadget, by adding the current node
; and then exploring all childnodes by recursively calling itself.
;
Procedure FillTree(*CurrentNode, CurrentSublevel)

  ; Ignore anything except normal nodes. See the manual for
  ; XMLNodeType() for an explanation of the other node types.
  ;
  If XMLNodeType(*CurrentNode) = #PB_XML_Normal
  
    ; Add this node to the tree. Add name and attributes
    ;
    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)
        
        
    ; Now get the first child node (if any)
    ;    
    *ChildNode = ChildXMLNode(*CurrentNode)
    
    ; Loop through all available child nodes and call this procedure again
    ;
    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$)

    ; Note: 
    ;   The LoadXML() succeed if the file could be read. This does not mean that
    ;   there was no error in the XML though. To check this, XMLStatus() can be
    ;   used.
    ;
    ; Display an error message if there was a markup error
    ;
    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("Error", Message$)
    EndIf
    
    ; Note:
    ;   Even if there was an error in the XML, all nodes before the error position
    ;   are still accessible, so open the window and show the tree anyway.
    ;
    If OpenWindow(#Window, 0, 0, 500, 500, "XML Example", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
      TreeGadget(#TreeGadget, 10, 10, 480, 480)
      
      ; Get the main XML node, and call the FillTree() procedure with it
      ;
      *MainNode = MainXMLNode(#XML)      
      If *MainNode
        FillTree(*MainNode, 0)
      EndIf
      
      ; Expand all nodes for a nicer view
      ;
      For i = 0 To CountGadgetItems(#TreeGadget) - 1
        SetGadgetItemState(#TreeGadget, i, #PB_Tree_Expanded)
      Next i
      
      ; Wait for the window close event.
      ;
      Repeat
        Event = WaitWindowEvent()
      Until Event = #PB_Event_CloseWindow
    EndIf
        
  Else
    MessageRequester("Error", "The file cannot be opened.")
  EndIf

Re: Wie Ende des xml auslesen feststellen ?

Verfasst: 11.09.2016 20:22
von man-in-black
Hi,

ich bin mir jetzt nicht sicher, was du genau erreichen willst. Solange du das nicht in einem Thread aufrufst,
ist die XML Bearbeitung beendet, wenn die "oberste" Procedure beendet ist.

Code: Alles auswählen

If *MainNode
  FillTree(*MainNode, 0)     ;<<<<
  Messagerequester("","juhu, bin fertig")
EndIf
Sofern du es doch parallelisieren willst (Thread), dann kannst du den obigen Codeausschnitt in einer weiteren
Prodedure kapseln.

Code: Alles auswählen

#Custom_XML_End = #PB_Event_FirstCustomValue + 1
Procedure XMLVerarbeitung(dummy)
  FillTree(...)
  PostEvent(#Custom_XML_End)
Endprocedure

... ;knopfdruck etc
CreateThread(@XMLVerarbeitung(),dummy)

...;eventverarbeitung
Es geht natürlich auch in der bereits vorhandenen Procedure, dann musst du aber die Ebene prüfen, bevor ein Event gefeuert wird.
Wenn du dein Ansinnen weiter präzisierst, kann man besser helfen ;)

MFG
MIB

Re: Wie Ende des xml auslesen feststellen ?

Verfasst: 11.09.2016 22:42
von schleicher
Zu meiner genaueren Vorgehensweise. Ich lasse schon ab der *MainNode das ganze in einem thread laufen. Das was mir feht, ist das Ende, also wenn der letze Knotenpunkt aufgerufen wurde. Ich habe eine sehr große xml-Datei die ca. 2 min braucht zu bearbeiten(einlesen in Structuren). Da dachte ich , ich lade erst das HauptWindow, wenn die xml fertig geladen ist. Die CurrentNoden werden ebenfalls per Thread abgerufen, das ich per Postevent() den Fortschritt anzeigen lassen kann. Mir fehlt halt nur das Ende der xml, um das Hauptfenster erscheinen zu lassen. Wenn die Mainnode fertig ist, dann sind die Unterknoten lange nicht fertig. Mein Gedanke war, eventuell die Zeilen der Xml im Vorhinein zu zählen(openfile(xml)und dann mit readfile() die Zeilenanzahl ermitteln, und dann beim abarbeiten xml dadurch das Ende zu ermitteln, doch ist das die schnellste Varinte ?

Re: Wie Ende des xml auslesen feststellen ?

Verfasst: 11.09.2016 22:52
von schleicher
man-in -black

Sofern du es doch parallelisieren willst (Thread), dann kannst du den obigen Codeausschnitt in einer weiteren
Prodedure kapseln.

Code: Alles auswählen

#Custom_XML_End = #PB_Event_FirstCustomValue + 1
Procedure XMLVerarbeitung(dummy)
  FillTree(...)
  PostEvent(#Custom_XML_End)
Endprocedure
Das muss ich mir morgen mal genauer anschauen. Wenn das funktioniert, dann wäre das die Lösung. Ich melde mich. Danke erst einmal für den Tip.

Re: Wie Ende des xml auslesen feststellen ?

Verfasst: 12.09.2016 10:23
von man-in-black
Hi,

verstehe ich das richtig, dass du baumartig jeden Knoten in einem neuen Thread aufrufst? Ich kenne nur wenige Szenarien,
die dies rechtfertigen. In der Regel musst du eh warten, bis alle Daten eingelesen wurden, bevor du sie verarbeiten kannst.
Da reicht doch ein großer Thread?!

Was soll dein Thread denn bezwecken? Doch nur, dass du die GUI noch nutzen kannst, oder? /:->

PS: Falls du einen Fortschrittsbalken vorsehen willst:
Mir fehlt halt nur das Ende der xml, um das Hauptfenster erscheinen zu lassen. Wenn die Mainnode fertig ist, dann sind die Unterknoten lange nicht fertig. Mein Gedanke war, eventuell die Zeilen der Xml im Vorhinein zu zählen(openfile(xml)und dann mit readfile() die Zeilenanzahl ermitteln, und dann beim abarbeiten xml dadurch das Ende zu ermitteln, doch ist das die schnellste Varinte ?
Das mit der Endgröße ist immer ein Problem. Es wird deine Ladezeiten vermutlich stark erhöhen, da du in der Regel die Datei
zweimal abarbeitest. Wenn du schon Zeilen zählen willst, dann lad die Datei selbst in den Speicher und "catch"e diesen nurnoch für die XML. Die Festplatte ist immer ein Flaschenhals.

Re: Wie Ende des xml auslesen feststellen ?

Verfasst: 12.09.2016 20:44
von schleicher
Habe das nun mit der Kapselung gemacht und funktioniert ! Danke