Hat jemand das XML-Modul?

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

DivineDominion

Betreff: Hat jemand das XML-Modul?

BeitragDi, März 29, 2005 14:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Grüße Bürger

Hat jemand das XML-Modul für BMax noch? Der Autor ahts auf bmax.com weggenommen, weil ihm die Pointerkritik nicht gefiel. Ich möchte aber nicht UNBEDINGT einen eigenen Parser schreiben. Wink

Danke schonmal
christian.tietze@gmail.com - https://christiantietze.de
macOS

Jolinah

BeitragDi, März 29, 2005 19:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich denke mein Parser ist schlechter und noch nicht ganz ausgereift, aber vielleicht reicht das ja.

Er ist so ähnlich wie der XML Parser von PHP, Eventbasiert:

Parser (Modul):
Code: [AUSKLAPPEN]

Strict

Module pub.HtmlParser

ModuleInfo "Author: Jolinah"
ModuleInfo "Version: 0.2"

Import brl.linkedlist
Import brl.retro

Type THtmlAttribute
   Field key:String
   Field value:String
End Type

Type THtmlParser

   'Events
   Global OnOpenTag(tag:String, attrs:TList)
   Global OnInnerText(tag:String, text:String)
   Global OnCloseTag(tag:String)

   Function RemoveSpaces:String(text:String)
      For Local i:Int = 0 To 31
         text = Replace(text, Chr(i), "")
      Next
      Return text
   End Function

   Function Parse(filename:String)
      Local file = ReadFile(filename)
      If Not file Then Return False
       
      Local tag:String = ""
      Local old_tag:String = ""
      Local attrs:TList = CreateList()
      Local attr:THtmlAttribute = Null
      Local open_tag:Byte = False
      Local close_tag:Byte = False
      Local inner_text:Byte = False
      Local text:String = ""
      Local value:Byte = False
      Local prev_c:String = ""
       
      While Not Eof(file)
         Local c:String = Chr(ReadByte(file))
         
         c = RemoveSpaces(c)
         If c = "" Then Continue
         
            Select c
               'HTML Tag Beginn
               Case "<"
                  'Wenn es schon ein geöffnetes Tag gab und bereits der innere Text ausgelesen wurde..
                  If inner_text And (Len(text) > 0) Then
                     inner_text = False         'Innerer Text abgeschlossen
                     close_tag = False        'Kein schliessendes Tag
                     open_tag = True         'Nun folgt ein Close Tag
                     text = RemoveSpaces(text)   'Tabulator + Zeilenumbruch etc. entfernen
                     OnInnerText(tag, text)      'Event für inneren Text wird ausgelöst
                     text = ""            'Text zurücksetzen
                     old_tag = tag
                     tag = ""            'Tag zurücksetzen
                  Else
                     open_tag = True         'Ansonsten ist es ein öffnendes Tag
                     inner_text = False         'Innerer Text Modus ausschalten
                     close_tag = False         'Endtag Modus ausschalten
                     old_tag = tag            'Tag zurücksetzen
                     tag = ""
                  EndIf

               'Slash
               Case "/"
                  'Wenn das vorherige zeichen ein '<' war und jetzt ein '/' kommt dann ist es kein öffnendes
                  'sondern ein schliessendes Tag
                  If prev_c = "<" And open_tag Then
                     open_tag = False
                            close_tag = True
                  EndIf
               
               'HTML Tag Ende
               Case ">"
                  'Wenn das aktuelle Tag ein beginnendes Tag ist...
                  If open_tag Then
                     open_tag = False         '.. so ist es nun abgeschlossen
                     close_tag = False         'Endtag Modus auf jedenfall ausschalten
                     inner_text = True      'wird es noch ein Endtag geben

                     If prev_c = "/"
                        tag = old_tag
                     EndIf
          
                   
                     If Not attr = Null         'Wenn vorher noch ein Attribut ausgelesen wurde
                        ListAddLast(attrs, attr)   'dieses noch in die Liste eintragen..
                     EndIf
                   
                     Local remove:TList = CreateList()
                     For Local a:THtmlAttribute = EachIn attrs
                        a.value = Replace(a.value, Chr(34), "")      'Anführungszeichen entfernen
                        a.key = Upper(a.key)               'Uppercase
                        If a.key = " " Or a.key = "" Then
                           ListAddLast(remove, a)      'Ungültiges Element
                        EndIf
                     Next
                   
                     'Ungültige Elemente aus Attributliste löschen
                     For Local a:THtmlAttribute = EachIn remove
                        ListRemove(attrs, a)
                     Next
                     ClearList(remove)
                   
                     OnOpenTag(Upper(tag), attrs)      'Event für öffnendes Tag auslösen

                     attrs.Clear()         'Attributenliste leeren
                     attr = Null            'Aktuelles Attribut auf Null setzen
                     value = False         'Beim nächsten Attribut nicht value sondern key des Attributs lesen

                  'Wenn das aktuelle Tag ein Endtag ist...
                  Else If close_tag Then
                     inner_text = False         'Inneren Text Lesemodus auf jedenfall ausschalten
                     close_tag = False         'Endtag Lesemodus ausschalten
                     OnCloseTag(Upper(tag))         'Closetag Event auslösen
                  EndIf

               'Alle anderen Zeichen lesen
               Default
             
                  'Wenn der Lesemodus auf öffnendes Tag gesetzt ist...
                  If open_tag
               
                     'Wenn noch kein Attribut existiert
                     If attr = Null Then
                        If c = " "                  'Bei Lücke ein Attribut erstellen
                           attr = New THtmlAttribute
                           value = False            'value auf False setzen damit Attributname gelesen wird
                        Else
                           tag :+ c               'Wenn keine Lücke dann an Tag namen anhängen
                        EndIf

                     'Wenn schon ein Attribut existiert
                     Else
                        If c = " "                  'Bei Lück das letzte Attribut der Liste hinzufügen
                           ListAddLast(attrs, attr)
                           attr = New THtmlAttribute      'Neues Attribut erstellen
                           value = False            'Lesemodus so setzen das Attributname gelesen wird
                           Continue
                        EndIf
                     
                        If c = "="                  'Wenn das aktuelle Zeichen ein '=' ist..
                           value = True            'Lesemodus umstellen so dass Attributwert gelesen wird.
                           Continue
                        EndIf
                     
                        If value                  'Attributwert soll gelesen werden
                           attr.value :+ c             
                        Else                     'Attributname soll gelesen werden
                           attr.key :+ c
                        EndIf
                  EndIf

                  'Wenn der Lesemodus auf Endtag gesetzt ist...
                  Else If close_tag
                     tag :+ c                     'Zeichen an Tagname anhängen
                   
                  'Wenn der Lesemodus auf Innerer Text gesetzt ist...
                  Else If inner_text
                     text :+ c                     'Zeichen am Text anhängen
                  EndIf
         End Select         

         prev_c = c      'Vorheriges Zeichen setzen..
             
      Wend
       
      CloseFile(file)
       
      attrs.Clear()
      attr = Null
       
      Return True
   End Function
       
End Type


BMax Beispiel:
Code: [AUSKLAPPEN]

Strict

'Eventhandler festlegen
THtmlParser.OnOpenTag = open_tag
THtmlParser.OnInnerText = inner_text
THtmlParser.OnCloseTag = close_tag

'File parsen
Global out:String = ""
THtmlParser.Parse("test.txt")

'Ausgeben
Print out

'Eventhandler für beginnende Tags
Function open_tag(tag:String, attrs:TList)
   out :+ "<" + tag
   
   For Local a:THtmlAttribute = EachIn attrs
      out :+ " " + a.key + "=" + Chr(34) + a.value + Chr(34)
   Next
   
   out :+ ">"
End Function

'Eventhandler für Inhalt zwischen zwei Tags
Function inner_text(tag:String, text:String)
   out :+ text
End Function

'Eventhandler für Endtags
Function close_tag(tag:String)
   out :+ "</" + tag + ">"
End Function


test.txt die vom Beispiel verwendet wird:
Code: [AUSKLAPPEN]

<html>
<head>
<title>Titel der Seite</title>
<link rel="stylesheet" type="text/css" media="screen" href="bla.css" />
</head>
<body bgcolor="#000000">
<div>Bla</div>
</body>
</html>


Zu erwähnen ist noch das der inner_text Event nur bei den innersten Elementen ausgelöst wird.

Code: [AUSKLAPPEN]

<a><b>bla</b></a>


Hier wird also für das a tag kein Inner_Text Event ausgelöst, nur für B.
  • Zuletzt bearbeitet von Jolinah am Mi, März 30, 2005 16:12, insgesamt 2-mal bearbeitet

DivineDominion

BeitragMi, März 30, 2005 2:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm, sieht codetechnishc genauso komisch aus, wie das, was ich mir zusammengehauen hab vorhin Smile

Das Ding interpretiert XML sehr fein, auch wenn ichs Zeilenweise mache während du es Byteweise machst (was natürlich besser ist, mist Smile).
Habe nur nichts für inner_text. Ärgere mich da schon sehr, ich probiere deins mal aus Smile


Edit: Werde aus der Ausgabe deiner Testdatei nicht ganz schlau...
Code: [AUSKLAPPEN]
<HTML> </HEAD><TITLE>Titel der Seite</TITLE><LINK REL="stylesheet" TYPE="textcss" MEDIA="screen" HREF="bla.css"></HEAD><BODY BGCOLOR="#000000"> </DIV></DIV></BODY></HTML>



Hier das was ich mir grade aus den Fingern gesaugt habe. Mir viel nix besseres ein was nach Scriptsprache aussah Smile
Zitat:

Code:
<script>
<let var="a" value="anton" />
<text>
Hallo du alte Gurke, <valueof var="a" />!
</text>
</script>

Ergebnis:
<SCRIPT><LET VAR="a" VALUE="anton"><TEXT>Hallo du alte Gurke, </VALUEOF VAR="A" ></TEXT></SCRIPT>


Warum er das <let .../> akzeptiert aber das <valueof .../> nicht, verstehe ich nicht ganz Smile Genauso in deinem Beispiel von oben. Oder bist du noch am Arbeiten daran? Smile
christian.tietze@gmail.com - https://christiantietze.de
macOS

Jolinah

BeitragMi, März 30, 2005 8:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh, da haben sich ja noch paar Fehler eingeschlichen Wink

Naja das ganze ist schon noch in Entwicklung und ich wollte es eigentlich noch nicht veröffentlichen. Ich fand aber es hat schon recht gut funktioniert daher hab ichs mal gepostet. Leider funktioniert doch noch vieles nicht richtig wie es den Anschein hat Very Happy

Ich schau bei Gelegenheit nochmal drüber..


Edit:

Zitat:
Warum er das <let .../> akzeptiert aber das <valueof .../> nicht


Den Fall hab ich noch nicht behandelt das in nem Tag ein solches tag <tag /> sein kann. Hab nicht daran gedacht..

DivineDominion

BeitragMi, März 30, 2005 12:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Witzig Smile Ich habe nicht daran gedacht das man Text zwischen zwei Tags schreiben könnte Very Happy
christian.tietze@gmail.com - https://christiantietze.de
macOS

Jolinah

BeitragMi, März 30, 2005 15:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Naja es ist halt ein spezieller Fall Very Happy

Ich frage mich ob sowas nach XML Norm überhaupt geht, hab ich zumindest noch nie gesehen.

Entweder is der Text doch zwischen zwei Tags oder dann sind nur andere Tags drin, oder irre ich mich?

Code: [AUSKLAPPEN]

<a>Hallo <b /> bla bla</a>


Sieht zumindest für mich komisch aus..
Wozu sollte man sowas auch machen?

Code: [AUSKLAPPEN]

<a>
  <b attr="true" />
  <c>text</c>
</a>


Ist doch viel übersichtlicher? Wink


Edit: Naja anscheinend gehts in XML doch, das .NET Studio hatte immerhin keine Probleme mit deinem xml code Wink

DivineDominion

BeitragMi, März 30, 2005 15:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Das aufzusplitten ist auch ne gute Idee! Darauf bin ich noch nicht gekommen, dann müsste ich nur die Textblöcke einlesen und nicht den text zerpflücken in Text, Tags, Text, ...
christian.tietze@gmail.com - https://christiantietze.de
macOS

Jolinah

BeitragMi, März 30, 2005 16:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab jetzt das Modul trotzdem mal angepasst. (ganz oben)

<tag /> innerhalb von normalen tags werden jetzt als öffnende Tags geparst, das heisst open_tag event mit Attributen wird ausgelöst.

Jedoch werden in deinem Fall zwei inner_text Events ausgelöst:

Code: [AUSKLAPPEN]

Open Tag -> text
Inner Text -> "Hallo du alte Gurke, "
Open Tag -> valueof mit attributen
Inner Text -> "!"
Close Tag -> text

DivineDominion

BeitragMi, März 30, 2005 16:30
Antworten mit Zitat
Benutzer-Profile anzeigen
WErd nur noch nicht so recht schlau draus wie ich das jetzt als scriptinterpreter missbrauchen kann - wills ja nicht auf einen schlag rendern oder so Very Happy
christian.tietze@gmail.com - https://christiantietze.de
macOS

Jolinah

BeitragMi, März 30, 2005 16:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm.. jo das könnte schwierig werden Wink

Vor allem weil xml ja eigentlich nicht für scripting vorgesehen ist (Beschreibungssprache).
 

Dreamora

BeitragMi, März 30, 2005 17:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm wenn du es für scripting nutzen möchtest ... warum nutzt du dafür nicht Pub.LUA?
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DivineDominion

BeitragMi, März 30, 2005 23:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Weil das für mich nichts bringt. Möchte nicht das ganze Script ausführen sondern nur Zeilenweise nacheinander abarbeiten. Zum Beispiel für Kamerabewegungen und sowas nacheinander. Möchte das nicht alles cachen wenn ich LUA schon nehme, da kann ichs auch selber machen und nach parsen speichern.
christian.tietze@gmail.com - https://christiantietze.de
macOS

Jolinah

BeitragDo, März 31, 2005 15:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Ohne zu cachen müsste man wohl die File die ganze Zeit geöffnet halten und zu gegebenem Zeitpunkt eine Zeile auslesen...

Aber mit cachen wäre relativ einfach:

test.txt
Code: [AUSKLAPPEN]

<script>
  <command name="movecam" x="10.0" y="20.0" z="30.0" />
  <command name="movecam" x="10.0" y="30.0" z="40.0" />
</script>


Code: [AUSKLAPPEN]

Type ScriptCommand
  Field command:String
  Field attrs:String[]
End Type

THtmlParser.OnOpenTag = open_tag
THtmlParser.OnInnerText = inner_text
THtmlParser.OnCloseTag = close_tag

Global cmds:TList = CreateList()
Global xpos = 100, ypos = 100

THtmlParser.Parse("test.txt")

Local cmd_timer = MilliSecs() + 2000

Graphics(400,400,0)

Repeat
Cls

   If MilliSecs() >= cmd_timer
      Local cmd:ScriptCommand
      Try
         cmd = ScriptCommand(cmds.RemoveFirst())
      Catch ex:Object
      End Try
      
      If cmd <> Null
         If cmd.command = "movecam"
            xpos = Int(cmd.attrs[0])
            ypos = Int(cmd.attrs[1])
         EndIf
      EndIf
         
      cmd_timer = MilliSecs() + 2000
   EndIf
   
   DrawRect(xpos, ypos, 50, 50)      

Flip
Until KeyHit(KEY_ESCAPE)

cmds.Clear()

FlushMem
End



Function open_tag(tag:String, attrs:TList)
   If tag = "COMMAND"
      Local cmd:ScriptCommand = Null
      Local i:Int = 0
      
      For Local attr:THtmlAttribute = EachIn attrs
         If attr.key = "NAME"
            cmd = New ScriptCommand
            cmd.command = attr.value
            cmd.attrs = New String[CountList(attrs)-1]
            i = 0
         Else If cmd <> Null
            cmd.attrs[i] = attr.value
            i :+ 1
         EndIf
      Next
      
      ListAddLast(cmds, cmd)      
   EndIf
End Function


Function inner_text(tag:String, text:String)

End Function


Function close_tag(tag:String)

End Function

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group