WaBis

walter.bislins.ch

Wxml: Anwendung

Wxml : Download | Einführung | Anwendung | Referenz
Bei der Anwendung des Wxml-Moduls geht es darum, eine Anwendungs-Datenstruktur in eine hierarchische Tag-Struktur umzuwandeln, die dann zwecks Speicherung in einer Datei in einen String im WXML-Format umgewandelt wird und umgekehrt.

Die Anwendungs-Datenstruktur enthält oft redundante Daten, die nicht unbedingt in einer Datei gespeichert werden müssen, sondern zur Laufzeit aus den gespeicherten Daten berechnet werden können. Zudem will man vielleicht Daten verschlüsselt oder sonst wie codiert in der Datei speichern. Daher ist die zu erzeugende hierarchische Tag-Struktur nicht unbedingt eine 1:1 Abbildung der Anwendungs-Datenstruktur.

Unter OOP-Richtlinien programmiert man so, dass jedes Anwendungs-Objekt Funktionen bekommt, die sich selbst in eine Tag-Struktur umwandeln oder sich selbst aus einer Tag-Struktur aufbauen können. Mehrere so erzeugte Tag-Strukturen können dann in ein Root-Tag gehängt werden, welches ins WXML-Format serialisiert und in einer Datei gespeichert werden kann. Umgekehrt liest man eine solche Datei ein, lässt das WXML-Format parsen und baut aus den so erzeugten Tags wieder die Anwendungs-Datenstruktur auf.

Anwendungsbeispiel

Unsere Anwendung soll eine Liste von Benutzern mit Benutzername, Passwort und Benutzertyp verwalten und ein paar globale Einstellungen speichern können. Die entsprechenden Objekte der Anwendung seien folgendermassen definiert:

class CAppli
  public Globals  ' as CGlobals
  public UserList ' as CUserList
  :
end class

class CGlobals
  public Language ' as string
  public LastDate ' as date
  :
end class

class CUserList
  public Users ' as array of CUser
  :
end class

class CUser
  public Name  ' as string
  public Pwd   ' as string
  public UType ' as string 
  :
end class

Jede Klasse erhält nun je eine Funktion SaveToXml, welche aus dem Objekt eine Tag-Struktur erzeugt, und eine Funktion LoadFromXml mit der umgekehrten Funktionalität.

Diese Funktionen sind für die Klassen CGlobals und CUser sehr einfach zu implementieren:

class CGlobals
  :
  function SaveToXml()
    dim tag
    set tag = NewXmlTag( "Globals" )
    tag.AddStr "Language", Language
    tag.AddDate "LastDate", LastDate
    set SaveToXml = tag
  end function

  sub LoadFromXml( aTag )
    Language = aTag.GetStrByName( "Language", "de" )
    LastDate = aTag.GetDateByName( "LastDate", Now )
  end sub
  :
end class

class CUser
  :
  function SaveToXml()
    dim tag
    set tag = NewXmlTag( "User" )
    tag.AddStr "Name", Name
    tag.AddStr "Pwd", Pwd
    tag.AddStr "UType", UType
    set SaveToXml = tag
  end function

  sub LoadFromXml( aTag )
    if aTag is Nothing then exit sub
    Name  = aTag.GetStrByName( "Name", "" )
    Pwd   = aTag.GetStrByName( "Pwd", "" )
    UType = aTag.GetStrByName( "UType", "gast" )
  end sub
  :
end class

Beachte, dass die Properties der Appli-Objekte in derselben Reihenfolge aus den Tags gelesen werden (GetXxxByName), wie die Tags erzeugt wurden (AddXxx), weil dadurch die Suche nach den Tags am schnellsten geht.

Für die User-Liste sieht SaveToXml folgendermassen aus:

class CUserList
  :
  function SaveToXml()
    dim tag, i
    set tag = NewXmlArrayTag( "UserList", UBound(UserList)+1 )
    for i = 0 to UBound(UserList)
      set tag.TagList(i) = UserList(i).SaveToXml()
    next
    set SaveToXml = tag
  end function
  :
end class

In diesem Fall wird also ein Tag-Knoten (Array-Tag) erzeugt, der alle User-Daten enthält. Die erzeugte Tag-Struktur sieht schematisch folgendermassen aus:

Tag: UserList
  Tag: User
    Tag: Name
    Tag: Pwd
    Tag: UType
  Tag: User
    Tag: Name
    Tag: Pwd
    Tag: UType
  :

Die zugehörige Umkehrfunktion LoadFromXml sieht wiefolgt aus:

class CUserList
  :
  sub LoadFromXml( aTag )
    dim sz, user, i
    UserList = Array()
    if aTag is Nothing then exit sub
    sz = UBound( aTag.TagList )
    if zs < 0 then exit sub
    redim UserList( sz )
    for i = 0 to sz
      set user = new CUser
      user.LoadFromXml aTag.TagList(i)
      set UserList(i) = user
    next
  end sub
  :
end class

Jetzt fehlen nur noch die Funktionen auf Appli-Ebene:

class CAppli
  :
  function SaveToXml()
    dim rootTag
    set rootTag = NewXmlTag( "Appli" )
    rootTag.AddTag Globals.SaveToXml()
    rootTag.AddTag UserList.SaveToXml()
    set SaveToXml = rootTag
  end function
 
  sub LoadFromXml( aRootTag )
    if aRootTag is Nothing then exit sub
    Globals.LoadFromXml  aRootTag.GetTagByName( "Globals" )
    UserList.LoadFromXml aRootTag.GetTagByName( "UserList" )
  end sub
  :
end class

Jetzt fehlen nur noch die Funktionen CAppli.SaveToFile und CAppli.LoadFromFile:

class CAppli
  :
  sub SaveToFile( aFilename )
    dim rootTag, wxmlString
    set rootTag = SaveToXml()
    wxmlString = rootTag.Serialize()
    FS.WriteFile aFilename, wxmlString
  end sub

  sub LoadFromFile( aFilename )
    dim wxmlString, rootTag
    wxmlString = FS.ReadFile( aFilename )
    set rootTag = NewXmlTag( "Appli" )
    rootTag.Parse wxmlString
    LoadFromXml rootTag
  end sub
  :
end class

Damit können die Appli-Daten sehr einfach in eine Datei gespeichert und wieder geladen werden:

dim Appli

set Appli = new CAppli
Appli.LoadFromFile "applidata.txt"
 :
Appli.SaveToFile "applidata.txt"

Eine solche Datei applidata.txt könnte folgendermassen aussehen:

<Globals>
  <Language>de</>
  <LastDate>31.12.2009 23:59</>
</Globals>
<UserList>
  <User>
    <Name>Admin</>
    <Pwd>****</>
    <UType>admin</>
  </User>
  <User>
    <Name>Gast</>
    <Pwd>****</>
    <UType>gast</>
  </User>
</UserList>

Weitere Infos zur Seite
Erzeugt Donnerstag, 2. Dezember 2010
von wabis
Zum Seitenanfang
Geändert Samstag, 18. Juli 2015
von wabis