DOMParser mit libxerces



  • Hi,

    ich versuche gerade Daten aus einer XML-Datei mithilfe der xerces-Bibliothek in mein Programm zu laden, aber irgendwie überfordert mich das ...

    Die xml-Datei sieht wie folgt aus:

    <ShipTypes>
    	<Ship name="Massengutfrachter Handymax-Klasse" costs="50000000" speed="28" size="40000" consumption=""></Ship>
    	<Ship name="Massengutfrachter Panamax-Klasse" costs="80000000" speed="24" size="70000" consumption=""></Ship>
    	<Ship name="Massengutfrachter Capesize-Klasse" costs="140000000" speed="20" size="200000" consumption=""></Ship>
    	<Ship name="OBC-Frachter" costs="120000000" speed="22" size="80000" consumption=""></Ship>
    	<Ship name="OBO-Frachter" costs="240000000" speed="20" size="150000" consumption=""></Ship>
    	<Ship name="Schwergutfrachter Crane-Klasse" costs="100000000" speed="24" size="30000" consumption=""></Ship>
    	<Ship name="Schwergutfrachter Factory-Klasse" costs="150000000" speed="22" size="60000" consumption=""></Ship>
    	<Ship name="Tanker LCC-Klasse" costs="200000000" speed="24" size="150000" consumption=""></Ship>
    	<Ship name="Tanker VLCC-Klasse" costs="350000000" speed="22" size="250000" consumption=""></Ship>
    	<Ship name="Tanker ULCC-Klasse" costs="500000000" speed="20" size="350000" consumption=""></Ship>
    	<Ship name="Tanker VPLUS-Klasse" costs="1000000000" speed="20" size="500000" consumption=""></Ship>
    	<Ship name="Gastanker Pioneer-Klasse" costs="200000000" speed="24" size="125000" consumption=""></Ship>
    	<Ship name="Gastanker Korea-Klasse" costs="400000000" speed="22" size="250000" consumption=""></Ship>
    	<Ship name="Kühlschiff Frost-Klasse" costs="60000000" speed="26" size="60000" consumption=""></Ship>
    	<Ship name="Kühlschiff Ice-Klasse" costs="110000000" speed="22" size="120000" consumption=""></Ship>
    	<Ship name="RoRo-Frachter Klasse 3" costs="100000000" speed="28" size="100000" consumption=""></Ship>
    	<Ship name="RoRo-Frachter Klasse 2" costs="170000000" speed="26" size="160000" consumption=""></Ship>
    	<Ship name="RoRo-Frachter Klasse 1" costs="280000000" speed="24" size="280000" consumption=""></Ship>
    	<Ship name="ConRo-Frachter" costs="350000000" speed="24" size="100000" consumption=""></Ship>
    	<Ship name="Containerschiff New-York-Klasse" costs="100000000" speed="24" size="60000" consumption=""></Ship>
    	<Ship name="Containerschiff Hamburg-Klasse" costs="200000000" speed="24" size="100000" consumption=""></Ship>
    	<Ship name="Containerschiff Emma-Klasse" costs="280000000" speed="24" size="150000" consumption=""></Ship>
    </ShipTypes>
    

    Das Parsen mit der XercesDOMParser-Klasse funktioniert auch soweit und ich kann auch das erste Element der Datei (<ShipTypes>) auslesen, aber ich schaffe es irgendwie nicht von dem <ShipTypes>-Element auf die <Ship>-Elemente und deren Attribute zuzugreifen, ich habe schon einiges Versucht, den für mich erfolgsversprechendsten Versuch schick ich einfach mal mit:

    //ShipTypes-Node
    DOMElement* RootNode = (DOMElement *)File->getDocumentElement();
    
    DOMElement* ShipNode = (DOMElement *)RootNode->getFirstChild();
    name=XMLString::transcode(ShipNode->getAttribute(XMLString::transcode("name")));
    

    So schwierig kann das doch nicht sein oder? Hab ich vielleicht ein Fehler in der XML-Datei?



  • Du musst die Nodes des Document Element zuerst fragen, ob sie überhaupt Elemente sind. Denn auch Attribute, Text, Kommentare sind Nodes. Erst dann ist der Cast nach DOMElement erlaubt.

    Übrigens: Mit C++-Casts kannst Du Dich vor falschen Casts schützen. Deine Methode wird im Zweifel einfach nur crashen (was Du sicher schon bemerkt hast).

    DOMElement* RootNode = static_cast<DOMElement *>(File->getDocumentElement()); // static_cast, weil DocumentElement immer ein DOMElement ist.
    
    DOMNode* node = RootNode->getFirstChild();
    while (node != 0 && node->getNodeType() != DOMNode::ELEMENT_NODE) {
        node = node->getNextSibling();
    }
    if (node != 0) {
        DOMElement* firstElement = static_cast<DOMElement*>(node); // static_cast, weil ELEMENT_TYPE immer ein DOMElement ist.
    }
    
    // oder aber (weniger schön, weil vermutlich Laufzeitintensiver):
    DOMNode* node = RootNode->getFirstChild();
    DOMElement* element = 0;
    while (node != 0) {
        element = dynamic_cast<DOMElement*>(node); // dynamic_cast, weil das Laufzeitsystem feststellen soll, ob node tatsäöchlich ein Element ist
        if (element != 0) break;
    
        node = node->getNextSibling();
    }
    

    getNextSibling, getNodeType und DOMNode::ELEMENT_NODE sind jetzt aus dem Gedächtnis, es kann sein dass die geringfügig anders heißen.



  • Cool, danke, fuktioniert. Dazu hab ich dann aber noch eine Frage: Wenn ich davor dann die Anzahl der <Ship>-Nodes herrausfinden möchte dann klappt folglich ja nicht mit RootNode->getChildNodes()->getLength() (weil das dann ja auch die Text-Nodes etc. mitzählt). Wie kann ich das dann machen?


Anmelden zum Antworten