wie XML intern speichern?



  • Da ich für mehrere kleine Programme immer wieder Config-Dateien brauche, bin ich gerade dabei, eine Funktion zu basteln, die mir immer wieder die Tags und Inhalte der Config-Datei parsen, damit diese intern weiterverarbeitet werden. Diese Dateien sind XML ähnlich aufgebaut. Das heißt, dass ich nicht sonderlich auf die XML Standards achte, sondern einfach nur meine Dateien parsen möchte. Ich gehe diese Dateien also in meiner Funktion durch und reagiere auf < bzw. >. Somit kann ich zwischen Tags und Inhalten unterscheiden. Nun muss ich diese jedoch in einer Art Baum oder Liste speichern, um sich im eigentlichen Programm weiterzuverarbeiten. Wie könnte ich dies machen? Mir ist vorallem auch wichtig, dass der Ebenencharakter vom meinen Dateien nicht verloren geht.

    Mit Ebenencharakter meine ich z.B. folgendes:

    <root><name>flo</name><passwort>blub</passwort></root>
    

    Nun möchte ich, dass ich später in meiner Liste/Baum erkennen kann, dass "name" in "root" liegt und "flo" ein Inhalt von "name" ist ...



  • ein baum hilft dir, wie du schon selbst sagst. gib jeder einzelnen node einen namen (den des tags, also z.b. 'name') und wenn du in der hirarchie eins weiter runter kommst, nimmst du die aktuelle node einfach als parent, und machst wie am anfang weiter. das ganze sieht danach dann etwa so aus:

    <root>
      <name>Peter</name>
      <passwort>geheim</passwort>
      <beschreibung>
        <kurz>peter ist nicht groß</kurz>
        <lang>blablablablablablablablabla</lang
      </beschreibung>
      <alter>10</alter>
    </root>
    
    root
     |
     + name: Peter
     + passwort: geheim
     + beschreibung
        + kurz: peter ist nicht groß
        + lang: blablablablablablablablabla
     + alter: 10
    

    pass aber beim parsen auf ein paar dinge auf: z.b. open/close tags, hirarchien, sonderzeichen, "</>" im inhalt der config-variablen.
    hab mal einen kleinen xml-parser geschrieben, wenn du willst, kann ich ihn dir ja mailen, vielleicht kannst was davon gebrauchen



  • Einen Baum realisierst du in etwa so (Pseudocode):

    struct Node {
      int data;
    
      // ...
    
      Node** children;
      int count;
    }
    

    Du speicherst die Daten in dem Node und merkst dir in ihm seine Children. Dazu brauchst du allerdings i.d.R. dynamischen Speicher. DUrchwandern kannst du das ganze rekursiv.



  • Korbinian: Würde mich sehr freuen, wenn Du mir das Teil mailen könntest. Adresse ist florian.doerr[at]web.de ...

    Habe mit Bäumen bis jetzt nicht gearbeitet, habe das Wort nur gelegentlich in meinen Suchen hier im Board gelesen. Aber wie ich das bis jetzt von MaSTaH verstanden habe, muss ich mir ein Struct zusammenbasteln, in welchem ich den jeweiligen Inhalt speichere. Dazu ein kommt der Name des jeweils "höheren" Structs hinein. MaSTaH, für was steht bei dir die Variable count? Du hast außerdem gesagt (was ich auch sinngemäß schon nicht verstehe), dass ich den Speicher für die einzelnen "Nodes" dynamisch belegen muss. Warum und wie?

    🙂



  • Nein, du speicherst die Unterzweige des jeweiligen Zweiges in Children. Deswegen auch count.



  • struct Node { 
      int data; 
      char *name;    // Name dieses Nodes
      char *Data;    // Daten des Nodes
      // ... 
    
      int count;    // Anzahl der Children die von diesem Node aus definiert sind
      Node** children; 
    }
    

    MaSTaH will mit malloc einen Vektor von Pointer mit Count Elementen erzeugen, in jedem Element dieses Vektores wird der Platz für einen Node allokiert, un dies so lange bis der ganze Baum gebildet ist.
    Da du Memory Allokieren must (und auch wieder freigeben), spricht man von dynmaischer Speicher-verwaltung.

    [Ab hier editiert]

    <root> 
      <name>Peter</name> 
      <passwort>geheim</passwort> 
      <beschreibung> 
        <kurz>peter ist nicht groß</kurz> 
        <lang>blablablablablablablablabla</lang 
      </beschreibung> 
      <alter>10</alter> 
    </root>
    

    Bildlich sähe so etwas wie folgt aus, die reale Implementierung muß aber besser gelöst werden.

    struct Node *BaseNode;
    if (0==(BaseNode=calloc(sizeof(struct Node),1)){ // Errorhandling}
    if (0==(BaseNode.name=calloc(sizeof(char),5)){ // Errorhandling}
       strcpy(BaseNode.name,"root");
    if (0==(BaseNode.Data=calloc(sizeof(char),1)){ // Errorhandling}
       strcpy(BaseNode.Data,"");
    BaseNode.count=4; // 4 Children name,passwort,beschreibung,alter
    if (0==(BaseNode.children=calloc(sizeof(struct Node),BaseNode.count)){ // Errorhandling}
    
    if (0==(BaseNode.children[0].name=calloc(sizeof(char),5)){ // Errorhandling}
       strcpy(BaseNode.children[0].name,"name");
    if (0==(BaseNode.children[0].Data=calloc(sizeof(char),6)){ // Errorhandling}
       strcpy(BaseNode.children[0].Data,"Peter");
    BaseNode.children[0].count=0; // no children
    .....
     if (0==(BaseNode.children[2].name=calloc(sizeof(char),13)){ // Errorhandling}
        strcpy(BaseNode.children[2].name,"Beschreibung");
     if (0==(BaseNode.children[2].Data=calloc(sizeof(char),1)){ // Errorhandling}
        strcpy(BaseNode.children[2].Data,"");
     BaseNode.children[2].count=2; // 2 Children kurz,lang
      if (0==(BaseNode.children[2].children=calloc(sizeof(struct Node),BaseNode.count)){ // Errorhandling}
      if (0==(BaseNode.children[2].children[0].name=calloc(sizeof(char),5)){ // Errorhandling}
         strcpy(BaseNode.children[2].children[0].name,"kurz");
      if (0==(BaseNode.children[2].children[0].Data=calloc(sizeof(char),strlen("peter ist nicht groß")+1)){ // Errorhandling}
         strcpy(BaseNode.children[2].children[0].Data,"peter ist nicht groß");
      BaseNode.children[2].children[0].count=0; // no children
    ....
    ....
    

Anmelden zum Antworten