XML Elementweise Einlesen



  • Hi ihr!
    Ich habe eine Ausbildung als Fachinformatiker in die Fachrichtung Anwendungsentwicklung begonnen und arbeite im Embedded System Bereich.

    Da unser Hauptprodukt ziemlich komplett aus C besteht, will ich das natürlich lernen : )

    Nun jetzt bin ich(sofern man das sagen kann) schon ein wenig mit C vertraut und mache mich jetzt dran,
    mir langsam so ein paar gängige Librarys draufzuschaffen.

    Im moment bin ich an der libxml angekommen und will eine Datei auslesen die wie folgt aussieht:

    <?xml version="1.0"?>
    <wurzl>
        <erstesElement>
            <ersterWert>1234</ersterWert>
            <zweiterWert>56789</zweiterWert>
            <dritterWert>21324354</dritterWert>
        </erstesElement>
        <zweitesElement>
            <ersterWert>4321</ersterWert>
            <zweiterWert>098765</zweiterWert>
            <dritterWert>06244</dritterWert>
        </zweitesElement>
        <drittesElement>
            <ersterWert>9999</ersterWert>
            <zweiterWert>1231111</zweiterWert>
            <dritterWert>3421342</dritterWert>
        </drittesElement>
    </wurzl>
    

    Ich möchte, die *Werte* jeweils zu den *Elementen* zuordnen können und sie dann in eine Linkd List packen
    die dann etwa so aussieht:

    struct subStruct {
        char *name; //der Name des Wertes (z.B. ersterWert)
        int val;    //der Wert zugehörig zum Name (z.B. 1234)
        struct subStruct *next; //nächster *wert* (z.B. zweiterWert)
    };
    
    struct linkedlist {
        char *name; //hier der Name des Elements (z.B. erstesElement)
        int val;    //noch nicht definiert, vllt vergebe ich dann noch ID's 
        struct subStruct *subStructLinkedList;
        struct linkedlist *next; //nächstes Element in der Liste (z.B. zweitesElement)
    };
    

    Bis jetzt sieht mein Project so aus:

    void print_element_names(xmlNode *a_node)
    {
        xmlNode *cur_node = NULL;
    
        for(cur_node = a_node; cur_node ; cur_node = cur_node->next) {
            if(cur_node->type == XML_ELEMENT_NODE) {
                printf("Node type: Element, name: %s\n", cur_node->name);
    
    /* hier liegt das Problem*/
                printf("Node type: Content, content: %s\n", cur_node->children->content);
            }
    
            print_element_names(cur_node->children);
        }
    }
    
    void readXMLFileIntoLinkedList(char *filename, struct linkedlist *linkedListOnTheStack)
    {
        if(checkForFile(filename) == 0) {
            perror("readXMLFileIntoLinkedList | filecheck fail");
            exit(1);
        }
    
        xmlDocPtr doc;
    
        if((doc = xmlParseFile(filename)) == 0) {
            perror("readXMLFileIntoLinkedList | cannot parse file");
            exit(1);
        }
    
        xmlNodePtr currentNodePntr;
        currentNodePntr = xmlDocGetRootElement(doc);
        print_element_names(currentNodePntr);
    }
    

    Ich bekomme auch schonmal Output:

    Node type: Element, name: wurzl
    Node type: Element, content:

    Node type: Element, name: erstesElement
    Node type: Element, content:

    Node type: Element, name: ersterWert
    Node type: Element, content: 1234
    Node type: Element, name: zweiterWert
    Node type: Element, content: 56789
    Node type: Element, name: dritterWert
    Node type: Element, content: 21324354
    Node type: Element, name: zweitesElement
    Node type: Element, content:

    Node type: Element, name: ersterWert
    Node type: Element, content: 4321
    Node type: Element, name: zweiterWert
    Node type: Element, content: 098765
    Node type: Element, name: dritterWert
    Node type: Element, content: 06244
    Node type: Element, name: drittesElement
    Node type: Element, content:

    Node type: Element, name: ersterWert
    Node type: Element, content: 9999
    Node type: Element, name: zweiterWert
    Node type: Element, content: 1231111
    Node type: Element, name: dritterWert
    Node type: Element, content: 3421342

    Jetzt seht ihr sicherlich, das zwischendrin immer mal wieder

    Node type: Element, content:

    leer da steht.

    Jetzt kann ich das so nicht benutzen um meine linked list richtig zu füllen, weil ich
    a) die Werte nicht ihrem Element sicher zuweisen kann
    b) die leeren contents nicht rausbekomme >_> wenn ich den content auf NULL oder "" oder xmlChar * a = "" prüfe, tut sich nix

    Vielleicht ist mein Ansatz ja auch schon falsch, ich weis es nicht wie ich die xml vernünftig auslesen kann.
    Das ist jetzt ganzschön viel geworden, wenn man das mal so umschreiben will was das Problem ist >_>

    Vielen Dank schonmal
    🙂



  • So wie das aussieht, ist das auch nicht leer, sonder da ist ein '\n' drin.
    Kannst du z.B. so überprüfen:

    /* hier liegt das Problem*/
                printf("Node type: Content, content: <%s>\n", cur_node->children->content);  // Achte auf die Positionen der <>
    

    Oder auf '\n' testen.

    Nebenbei passt dein Code nicht zur Ausgabe.

    printf("Node type: Element, name: %s\n", cur_node->name);
                printf("Node type: Content, content: %s\n", cur_node->children->content);
                        Node type: Element, content: Diese Kobination gibt es nicht
                                   ^^^^^^^  ^^^^^^^
    


  • Danke Dirk : )

    stimmt das mit dem rumgeprinte is doof notiert

    clevere Sache das mit dem <%s> : D

    Node type: Element, name: ersterWert
    Node type: Content, content: <1234>
    Node type: Element, name: zweiterWert
    Node type: Content, content: <56789>
    Node type: Element, name: dritterWert
    Node type: Content, content: <21324354>
    Node type: Element, name: zweitesElement
    Node type: Content, content: <
            >
    

    auf '\n' kann ich nicht testen, oder ich bin zu doof...
    weil cur_node->children->content ein "xmlChar " ist
    also hab ich nen xmlChar
    empty = "\n"; gemacht
    und versucht den xmlStrcmp zu benutzen,
    aber das geht auch in die Hose, genau der selbe output wie oben
    auch wenn ich versuche meinen prüf-xmlChar-Pointer auf "" oder " " zu setzen, passiert nix

    void print_element_names(xmlNode *a_node)
    {
        xmlNode *cur_node = NULL;
        xmlChar *empty = "\n";
    
        for(cur_node = a_node; cur_node ; cur_node = cur_node->next) {
            if(cur_node->type == XML_ELEMENT_NODE) {
                printf("Node type: Element, name: %s\n", cur_node->name);
    
                if(xmlStrcmp(cur_node->children->content, empty)) {
                    printf("Node type: Content, content: <%s>\n", cur_node->children->content);
                }
            }
    
            print_element_names(cur_node->children);
        }
    }
    


  • Da scheint noch mehr drin zu sein, als nur das '\n' (das > ist ziemlich weit rechts)
    Leerzeichen oder ein Tabulator könnten das sein. Auf alle Fälle Whitespace.

    Gibt es in der libxml eine Trimfunktion (zum entfernen von führenden/folgenden Whitespace)?
    Wenn nicht, musst du die selber machen.



  • Hi Dirk,

    ich seh da Gemeinsamkeiten : D

    <zweitesElement>
            <ersterWert>4321</ersterWert>
    
    Node type: Content, content: <
            >
    

    scheinen echt die whitespaces aus meiner *.xml file zu sein

    ich werd mich mal schlau machen ob es da eine trimm-fn gibt

    thx


Log in to reply