XML-Datei in Treegadget anzeigen {gelöst}

Für allgemeine Fragen zur Programmierung mit PureBasic.
sibru
Beiträge: 265
Registriert: 15.09.2004 18:11
Wohnort: hamburg

XML-Datei in Treegadget anzeigen {gelöst}

Beitrag von sibru »

Hallo Allerseits,
ich habe hier einen uralten Source zur Anzeige von XML-Dateiinhalten, der bisher toll gelaufen ist.
Nun werden nicht mehr alle Werte angezeigt

Code: Alles auswählen

Global *MainNode, Event, FileName$, FileRef$, Format, i, Win_B, Win_T, Win_X, Win_Y, WinNr, XML_GadNr, XML_Nr

Procedure FillTree(*CurrentNode, CurrentSublevel)
  Protected *ChildNode, Att$, Text$
  If XMLNodeType(*CurrentNode) = #PB_XML_Normal
    Text$ = GetXMLNodeName(*CurrentNode)
    If ExamineXMLAttributes(*CurrentNode)
      While NextXMLAttribute(*CurrentNode)
        If Att$ = "" : Att$ = " (Attribute: " : EndIf
        Att$ + XMLAttributeName(*CurrentNode) + "=" + #DQUOTE$ + XMLAttributeValue(*CurrentNode) + #DQUOTE$ + " "
      Wend
    EndIf
    If Att$>"" : Att$ + ")" : EndIf
    AddGadgetItem(XML_GadNr, - 1, Text$ + Att$, 0, CurrentSublevel)
    *ChildNode = ChildXMLNode(*CurrentNode)
    While * ChildNode <> 0
      FillTree(*ChildNode, CurrentSublevel + 1)
      *ChildNode = NextXMLNode(*ChildNode)
    Wend
  EndIf
EndProcedure

FileName$ = ProgramParameter()
If FileSize(FileName$)<10
  FileName$ = OpenFileRequester("XML-Datei auswählen", "", "XML-datei|*.XML", 0)
EndIf
If FileName$ = "" : End : EndIf
FileRef$ = #DQUOTE$ + GetFilePart(FileName$) + #DQUOTE$
XML_Nr = ReadFile(#PB_Any, FileName$)
Format = ReadStringFormat(XML_Nr)
CloseFile(XML_Nr)
XML_Nr = LoadXML(#PB_Any, FileName$, Format)
Win_X = 10
Win_Y = 10
Win_B = 600
Win_T = 200
WinNr = OpenWindow(#PB_Any, Win_X, Win_Y, Win_B, Win_T, "Datei " + FileRef$, #PB_Window_SystemMenu|#PB_Window_SizeGadget)
XML_GadNr = TreeGadget(#PB_Any, 0, 0, Win_B, Win_T)

*MainNode = MainXMLNode(XML_Nr)
If *MainNode : FillTree(*MainNode, 0): EndIf
For i = 0 To CountGadgetItems(XML_GadNr) - 1
  SetGadgetItemState(XML_GadNr, i, #PB_Tree_Expanded)
Next i
SetGadgetState(XML_GadNr, 0)

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
vielleicht liegt´s auch an der XML-Datei (Telefonbuch vonne FritzBox)
  • <?xml version="1.0" encoding="utf-8"?>
    <phonebooks>
    <phonebook name="Telefonbuch"><contact><category>0</category><person><realName>ADAC Service</realName></person><telephony
    nid="1"><number type="work" prio="1" id="0">08005101112</number></telephony><services /><setup /><features
    doorphone="0" /><mod_time>1534939336</mod_time><uniqueid>109</uniqueid></contact><contact><category>0</category><person><realName>Aldi Talk</realName></person><telephony
    nid="2"><number type="home" prio="1" id="0">0201 – 22099777</number><number
    type="mobile" prio="0" id="1"> 0177-177 1157</number></telephony><services /><setup /><features
    doorphone="0" /><mod_time>1508338087</mod_time><uniqueid>23</uniqueid></contact><contact><category /><person><realName>Andy</realName></person><telephony
    nid="1"><number type="mobile" vanity="" prio="1" id="0">015738182046</number></telephony><services /><setup><ringTone /></setup><mod_time>1500560453</mod_time><uniqueid>24</uniqueid></contact><contact><category>0</category><person><realName>Angela FN</realName></person><telephony
    nid="1"><number type="home" prio="1" id="0">04067999865</number></telephony><services /><setup /><features
    doorphone="0" /><mod_time>1519229622</mod_time><uniqueid>25</uniqueid></contact></phonebook>
    </phonebooks>
Jedenfalls werden die wirklich interessanten Felder (realName und number) ohne Attribute angezeigt, obwohl in der XML-Datei vorhanden und Exel kann sie auch lesen.
Fehler anscheinend bei NextXMLAttribute(*CurrentNode) in Proc FillTree(): hier werden einige Attribute übersprungen.
Kann mir da jemand auf die Sprünge helfen ?



_________________________________
Titel angepasst. -- Andesdaf
Zuletzt geändert von sibru am 26.01.2020 15:50, insgesamt 2-mal geändert.
Bild Bild
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: NextXMLAttribute erkennt nicht alle Attribute

Beitrag von Nino »

sibru hat geschrieben:Jedenfalls werden die wirklich interessanten Felder (realName und number) ohne Attribute angezeigt, obwohl in der XML-Datei vorhanden und Exel kann sie auch lesen.
Ein Element namens "realName" kommt in dem von dir geposteten XML-Code 4x vor und hat in keinem Fall irgendein Attribut. Die Attribute der "number"-Elemente werden hier alle dargestellt. Also alles OK soweit.

In deinem Code ist nicht zweckdienlich, dass die Zeile

Code: Alles auswählen

Text$ = GetXMLNodeName(*CurrentNode) + " (Attribute: "
vor

Code: Alles auswählen

If ExamineXMLAttributes(*CurrentNode)
steht. Dadurch steht in dem erzeugten Baum bei jedem Element " (Attribute: ", auch wenn das betr. Element gar keine Attribute hat. Deshalb ist die Darstellung irreführend.

Beim Starten des Codes sagt die aktuelle PB-Version 5.71 LTS:
Veraltete Funktion 'CreateGadgetList()' verwendet.
Genauer werde ich mir deinen Code erst ansehen (falls das überhaupt nötig ist, s.o.), wenn du dies und alles andere Überflüssige entfernt hast, das für die hier interessierende Frage keine Rolle spielt (nicht benutzte Konstanten und vieles mehr) und der Code außerdem so geschrieben ist, dass er mit EnableExplicit funktioniert.
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: NextXMLAttribute erkennt nicht alle Attribute

Beitrag von Nino »

Dein neuer Code ist nicht lauffähig:
Zeile 16: Syntax-Fehler

Code: Alles auswählen

      While * ChildNode <> 0
Wenn der Fehler korrigiert ist, zeigt der Code bei mir wie der vorige Code alle Attribute an.
Ich weiß also nach wie vor nicht, warum du schriebst:
Jedenfalls werden die wirklich interessanten Felder (realName und number) ohne Attribute angezeigt,
Was tatsächlich fehlt sind die Texte, die manche Knoten enthalten. Daher habe ich in der Prozedur 'FillTree()' einen Aufruf der Funktion 'GetXMLNodeText()' hinzugefügt. Von den Texten muss auch noch links stehender Leerraum entfernt werden.
Ich habe den Code insgesamt noch etwas geändert, z.B. enthält er jetzt keine globalen Variablen mehr. Die sollte man möglichst sparsam verwenden. Ansonsten macht man es sich nur unnötig schwer, ein Programm zu pflegen.

Damit man das im TreeGadget dargestellte Ergebnis besser prüfen kann, poste ich hier die XML-Datei nochmal in formatierter Form, die besser für Menschen lesbar ist.

Code: Alles auswählen

; PB 5.71 LTS

EnableExplicit

#WhiteSpace$ = " " + #TAB$ + #CRLF$

Procedure.s LTrim_Any(source$, charlist$=#WhiteSpace$)
   ; -- entfernt vom Anfang von 'source$' alle Zeichen,
   ;    die in 'charlist$' enthalten sind
   Protected *s.Character
   
   *s = @ source$
   While *s\c <> 0 And FindString(charlist$, Chr(*s\c)) <> 0
      *s + SizeOf(Character)
   Wend
   
   ProcedureReturn PeekS(*s)
EndProcedure


Procedure FillTree(XML_GadNr, *CurrentNode, CurrentSublevel)
   Protected *ChildNode, Text$, Att$
   
   If XMLNodeType(*CurrentNode) = #PB_XML_Normal
      Text$ = LTrim_Any(GetXMLNodeText(*CurrentNode))
      If Text$ <> ""
         Text$ = ": " + Text$
      EndIf   
      
      If ExamineXMLAttributes(*CurrentNode)
         If NextXMLAttribute(*CurrentNode)
            Att$ = " ( "
            Repeat
               Att$ + XMLAttributeName(*CurrentNode) + "=" + #DQUOTE$ + XMLAttributeValue(*CurrentNode) + #DQUOTE$ + " "
            Until NextXMLAttribute(*CurrentNode) = 0
            Att$ + ")"
         EndIf
      EndIf
      
      AddGadgetItem(XML_GadNr, - 1, GetXMLNodeName(*CurrentNode) + Text$ + Att$, 0, CurrentSublevel)
      
      *ChildNode = ChildXMLNode(*CurrentNode)
      While *ChildNode <> 0
         FillTree(XML_GadNr, *ChildNode, CurrentSublevel + 1)
         *ChildNode = NextXMLNode(*ChildNode)
      Wend
   EndIf
EndProcedure


Define FileName$, XML_Nr, Win_B, Win_H, XML_GadNr, i

FileName$ = OpenFileRequester("XML-Datei auswählen", "", "XML-Datei|*.xml", 0)
If FileName$ = ""
   Debug "Keine Datei ausgewählt."
   End
EndIf

XML_Nr = LoadXML(#PB_Any, FileName$)
If XML_Nr = 0 Or XMLStatus(XML_Nr) <> #PB_XML_Success
   Debug "Fehler beim Laden der XML-Datei."
   End
EndIf

Win_B = 500
Win_H = 700

If OpenWindow(#PB_Any, 10, 10, Win_B, Win_H, GetFilePart(FileName$)) = 0
   Debug "Fehler beim Öffnen des Fensters."
   End
EndIf
XML_GadNr = TreeGadget(#PB_Any, 0, 0, Win_B, Win_H)

FillTree(XML_GadNr, MainXMLNode(XML_Nr), 0)

For i = 0 To CountGadgetItems(XML_GadNr) - 1
   SetGadgetItemState(XML_GadNr, i, #PB_Tree_Expanded)
Next
SetGadgetState(XML_GadNr, 0)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

Code: Alles auswählen

<?xml version="1.0" encoding="utf-8"?>
<phonebooks>
   <phonebook name="Telefonbuch">
      <contact>
         <category>0</category>
         <person>
            <realName>ADAC Service</realName>
         </person>
         <telephony nid="1">
            <number type="work" prio="1" id="0">08005101112</number>
         </telephony>
         <services />
         <setup />
         <features doorphone="0" />
         <mod_time>1534939336</mod_time>
         <uniqueid>109</uniqueid>
      </contact>
      <contact>
         <category>0</category>
         <person>
            <realName>Aldi Talk</realName>
         </person>
         <telephony nid="2">
            <number type="home" prio="1" id="0">0201 – 22099777</number>
            <number type="mobile" prio="0" id="1"> 0177-177 1157</number>
         </telephony>
         <services />
         <setup />
         <features doorphone="0" />
         <mod_time>1508338087</mod_time>
         <uniqueid>23</uniqueid>
      </contact>
      <contact>
         <category />
         <person>
            <realName>Andy</realName>
         </person>
         <telephony nid="1">
            <number type="mobile" vanity="" prio="1" id="0">015738182046</number>
         </telephony>
         <services />
         <setup>
            <ringTone />
         </setup>
         <mod_time>1500560453</mod_time>
         <uniqueid>24</uniqueid>
      </contact>
      <contact>
         <category>0</category>
         <person>
            <realName>Angela FN</realName>
         </person>
         <telephony nid="1">
            <number type="home" prio="1" id="0">04067999865</number>
         </telephony>
         <services />
         <setup />
         <features doorphone="0" />
         <mod_time>1519229622</mod_time>
         <uniqueid>25</uniqueid>
      </contact>
   </phonebook>
</phonebooks>
sibru
Beiträge: 265
Registriert: 15.09.2004 18:11
Wohnort: hamburg

Re: NextXMLAttribute erkennt nicht alle Attribute {gelöst}

Beitrag von sibru »

Toll, der WhiteSpace-Filter hat´s gelöst !

!!! Danke !!!
Bild Bild
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: NextXMLAttribute erkennt nicht alle Attribute {gelöst}

Beitrag von Nino »

sibru hat geschrieben:Toll, der WhiteSpace-Filter hat´s gelöst !
Nein. Das Entfernen von links stehendem Leerraum sorgt lediglich dafür, dass das Ergebnis ordentlich aussieht. Die eigentliche Lösung des Problems war eine andere. Ich habe sie in meiner vorangegangenen Nachricht deutlich beschrieben ...
Antworten