Einfacher XML-Parser


  • Administrator

    Zaus schrieb:

    Hm habs auf "Vorkompilierte Header nicht verwenden" gestellt ändert aber leider nichts. Was mach ich falsch?

    Immer noch die gleiche Fehlermeldung oder was heisst "ändert nichts"?

    Zaus schrieb:

    Nochmal zu der Geschwindigkeit: Sobald das File einmal eingelesen ist und nur noch darin gesucht wird unterscheiden sich die Geschwindigkeiten nicht mehr groß?
    Also die angesprochene Sekunde bezog sich auf das einlesen?

    Ja, die Sekunde bezog sich ausschliesslich auf das Einlesen. Der Zugriff dürfte in etwa gleich sein. Vielleicht könnte RapidXML etwas schneller sein, aber so minimal, dass es wahrscheinlich schwierig wäre, dies zu messen 🙂

    Grüssli



  • Ja genau immer noch dieselben Fehlermeldungen und Warnungen wie davor.


  • Administrator

    Zaus schrieb:

    Ja genau immer noch dieselben Fehlermeldungen und Warnungen wie davor.

    Bist du sicher, dass du es auch in beiden Konfigurationen (Release und Debug) abgestellt hast? Ansonsten Projekt neu erstellen oder zuoberst ein #include "stdafx.h" rein, sofern du bereits einen solchen Header hast.

    Grüssli



  • Ja es war in allen Konfigurationen abgestellt...
    Mit neuem Projekt funktioniert es jetzt, danke.



  • Dravere schrieb:

    Der einzige Kritikpunkt an RapidXML ist, den ich finden konnte, dass es keinen XML Iterator hat. Das Iterieren über die Nodes ist ein wenig mühsam. Allerdings kann man sich auf die Schnelle einen eigenen Iterator basteln.

    Gibt es doch oder?

    namespace rapidxml
    
    {
    
        //! Iterator of child nodes of xml_node
    
        template<class Ch>
    
        class node_iterator
    
        {
    
        public:
    
            typedef typename xml_node<Ch> value_type;
    
            typedef typename xml_node<Ch> &reference;
    
            typedef typename xml_node<Ch> *pointer;
    
            typedef std::ptrdiff_t difference_type;
    
            typedef std::bidirectional_iterator_tag iterator_category;
    
            node_iterator()
    
                : m_node(0)
    
            {
    
            }
    
            node_iterator(xml_node<Ch> *node)
    
                : m_node(node->first_node())
    
            {
    
            }
    
            reference operator *() const
    
            {
    
                assert(m_node);
    
                return *m_node;
    
            }
    
            pointer operator->() const
    
            {
    
                assert(m_node);
    
                return m_node;
    
            }
    
            node_iterator& operator++()
    
            {
    
                assert(m_node);
    
                m_node = m_node->next_sibling();
    
                return *this;
    
            }
    
            node_iterator operator++(int)
    
            {
    
                node_iterator tmp = *this;
    
                ++this;
    
                return tmp;
    
            }
    
            node_iterator& operator--()
    
            {
    
                assert(m_node && m_node->previous_sibling());
    
                m_node = m_node->previous_sibling();
    
                return *this;
    
            }
    
            node_iterator operator--(int)
    
            {
    
                node_iterator tmp = *this;
    
                ++this;
    
                return tmp;
    
            }
    
            bool operator ==(const node_iterator<Ch> &rhs)
    
            {
    
                return m_node == rhs.m_node;
    
            }
    
            bool operator !=(const node_iterator<Ch> &rhs)
    
            {
    
                return m_node != rhs.m_node;
    
            }
    
        private:
    
            xml_node<Ch> *m_node;
    
        };
    
        //! Iterator of child attributes of xml_node
    
        template<class Ch>
    
        class attribute_iterator
    
        {
    
        public:
    
            typedef typename xml_attribute<Ch> value_type;
    
            typedef typename xml_attribute<Ch> &reference;
    
            typedef typename xml_attribute<Ch> *pointer;
    
            typedef std::ptrdiff_t difference_type;
    
            typedef std::bidirectional_iterator_tag iterator_category;
    
            attribute_iterator()
    
                : m_attribute(0)
    
            {
    
            }
    
            attribute_iterator(xml_node<Ch> *node)
    
                : m_attribute(node->first_attribute())
    
            {
    
            }
    
            reference operator *() const
    
            {
    
                assert(m_attribute);
    
                return *m_attribute;
    
            }
    
            pointer operator->() const
    
            {
    
                assert(m_attribute);
    
                return m_attribute;
    
            }
    
            attribute_iterator& operator++()
    
            {
    
                assert(m_attribute);
    
                m_attribute = m_attribute->next_attribute();
    
                return *this;
    
            }
    
            attribute_iterator operator++(int)
    
            {
    
                attribute_iterator tmp = *this;
    
                ++this;
    
                return tmp;
    
            }
    
            attribute_iterator& operator--()
    
            {
    
                assert(m_attribute && m_attribute->previous_attribute());
    
                m_attribute = m_attribute->previous_attribute();
    
                return *this;
    
            }
    
            attribute_iterator operator--(int)
    
            {
    
                attribute_iterator tmp = *this;
    
                ++this;
    
                return tmp;
    
            }
    
            bool operator ==(const attribute_iterator<Ch> &rhs)
    
            {
    
                return m_attribute == rhs.m_attribute;
    
            }
    
            bool operator !=(const attribute_iterator<Ch> &rhs)
    
            {
    
                return m_attribute != rhs.m_attribute;
    
            }
    
        private:
    
            xml_attribute<Ch> *m_attribute;
    
        };
    
    }
    

  • Administrator

    hasehasehase schrieb:

    Dravere schrieb:

    Der einzige Kritikpunkt an RapidXML ist, den ich finden konnte, dass es keinen XML Iterator hat. Das Iterieren über die Nodes ist ein wenig mühsam. Allerdings kann man sich auf die Schnelle einen eigenen Iterator basteln.

    Gibt es doch oder?

    Keine Ahnung woher du den hast. Ich konnte jedenfalls in der Dokumentation nichts dazu finden und was nicht dokumentiert ist, verwende ich normalerweise auch nicht.

    Grüssli



  • Dravere schrieb:

    Keine Ahnung woher du den hast.

    Download -> 4 Dateien. 🙂



  • Boost.PropertyTree ist ganz gut. Das verwendet intern RapidXML.
    http://www.boost.org/doc/libs/1_43_0/doc/html/property_tree.html



  • hasehasehase schrieb:

    Dravere schrieb:

    Keine Ahnung woher du den hast.

    Download -> 4 Dateien. 🙂

    Du solltest auch ausprobieren, was du da empfiehlst! Der iterators-code ist noch total verbuggt, kompiliert nicht! Z.B.

    node_iterator operator++(int)
            {
                node_iterator tmp = *this;
                ++this;
                return tmp;
            }
    

    ++this geht nicht, da this ein const pointer ist.
    Steht aber auch irgendwo in der Doku, dass die iterators noch nicht fertig sind.
    Wäre schön, wenn es dann auch irgendwo ein xml_node::end() gäbe, damit man auch dagegen prüfen könnte.



  • Ich hol den Thread nochmal hoch weil ich noch eine Frage habe.
    Hab bis jetzt mit TinyXML gearbeitet würde jetzt aber zum Vergleich auch gerne rapidxml ausprobieren.
    Ich schaffe es aber nicht einen Integer-Wert aus einem Attribut auszulesen.
    Bei TinyXML ging das zB mit QueryIntAttribute, bei rapidxml konnte ich aber nichts entsprechendes finden.

    Gruß Zaus



  • Schau dir doch die TinyXML-Sourcen an wie das da gemacht wird 😉
    XML kennt eigentlich nur Strings, deshalb gibt RapidMLX auch strings zurück. Wenn da ein anderer Wert drinnen steckt, muss das gecastet werden. boost::lexical_cast oder die Variante über std::stringstream gehen da genauso wie sscanf. Letzteres nimmt TinyXML. Wobei man streiten kann, ob die Konvertierung als Klassenmethode wirklich notwendig ist, denn im Prinzip kannst du den Aufruf sehr gut selber machen, ohne mehr Code schreiben zu müssen:

    int value;
    sscanf(rapixml_node.value(), "%d", &value);
    

    sollte gehen. sscanf hat natürlich auch einen return, den man abfangen kann 🙂



  • Danke 🙂

    Habe noch ne andere Frage und hoffe mal du kannst sie mir beantworten dann erspar ich den andereren nen extra Thread dazu.
    Beim ausführen des Programms bekomme ich folgende Nachricht im "Direktfenster" von VS:

    Eine Ausnahme (erste Chance) bei 0x7723b727 in MIDIrapid.exe: 0x000006BA: The RPC server is unavailable.

    Bei der TinyXML-Version erscheint dabei 3 mal diese Fehlermeldung, bei der rapidxml 4 mal. Wenn ich Debugge und den ersten Break-Point direkt zu anfang setze kommen diese Meldungen trotzdem. Das Programm läuft aber ganz normal und funktioniert auch...
    Konnte leider mit Google nicht rausfinden was das genau bedeutet und wie ich es beheben kann.

    Gruß Zaus



  • Benutzt doch PugiXml, hat auf mich einen sehr guten Eindruck gemacht.
    Simon



  • Wenn du eh RapidXML verwendest, schau auch mal Boots.PropertyTree (http://www.boost.org/doc/libs/1_41_0/doc/html/property_tree.html) an.
    Oder meine Page mit einem Vergleich aktueller Parser:
    http://lars.ruoff.free.fr/xmlcpp/



  • @Zaus: Dein Fehler hat absolut nichts mit RapidXml zu tun. Und Lösungsvorschläge kennt google zu Hauf. Z.B. gleich mehrere in diesem Thread:
    http://www.pc-special.net/windows-xp-f5/rpc-server-nicht-verfugbar-t15656.html
    Ich hab kein Windows, drum kann ich das nicht überprüfen.

    Und warum PugiXML empfehlen, wenn der OP RapidXML verwendet? Pugi bietet sicherlich einiges mehr an Features (ich mag es auch gerne :)), RapidXML hat aber auch seine Vorteile (z.B. komplett teamplate-basiert, man ist nicht auch "char" als Zeichentyp angewiesen; man muss nix separates kompilieren, da Header Only; nochmal schneller als PugiXML; ...)



  • Um das klar zu stellen:
    Boost.PropertyTree bringt einem gar nix, wenn man an XML interessiert ist! PropertyTree speichert alle Einträge in PCDATA-Nodes. Attribute, Kommentare, usw. kann man nicht nutzen. Ist halt auf ein reines "key=value" beschränkt. Wem das reicht, OK, aber die ständigen Hinweise "Boost.PropertyTree" wenn jemand nen XML-Parser haben will, sind manchmal schon nervig 🤡



  • Wenn du zufällig eine wxWidgets Anwendung hast, dann kann ich dir genügend Codeschnipsel posten.

    Ich stand vor ein paar Tagen vor dem gleichen Problem.



  • l'abra d'or schrieb:

    @Zaus: Dein Fehler hat absolut nichts mit RapidXml zu tun. Und Lösungsvorschläge kennt google zu Hauf. Z.B. gleich mehrere in diesem Thread:
    http://www.pc-special.net/windows-xp-f5/rpc-server-nicht-verfugbar-t15656.html
    Ich hab kein Windows, drum kann ich das nicht überprüfen.

    Ich dachte das Problem hat was mit meinem Programm zu tun, deshalb hab ich natürlich nur nach dem Fehler im Zusammenhang mit VS oder C++ Programmierung gesucht...
    Das mit dem 3bzw 4 mal war übrigens Quatsch. Die Fehlermeldung kommt immer dann wenn ich mit GetOpenFileName eine Datei lade. Die erforderlichen Dienste dazu sind alle gestartet... Naja vielleicht weiss ja jemand noch was dazu, wenn nicht scheint es auch nicht so schlimm zu sein.

    Zu den Parsern: Das passt schon so mit rapidxml und tinyxml. Beide funktionieren hervorragend. Brauche sie eh nur zum Auslesen von Attributen aus einer XML-Datei.
    Ein Geschwindigkeitsunterschied zwischen beiden ist allerdings nicht messbar (für das auslesen aus einer relativ kleinen xml-datei).



  • l'abra d'or schrieb:

    Um das klar zu stellen:
    Boost.PropertyTree bringt einem gar nix, wenn man an XML interessiert ist! PropertyTree speichert alle Einträge in PCDATA-Nodes. Attribute, Kommentare, usw. kann man nicht nutzen.

    Doch:
    http://www.boost.org/doc/libs/1_42_0/doc/html/boost_propertytree/parsers.html#boost_propertytree.parsers.xml_parser
    * The attributes of an XML element are stored in the subkey <xmlattr>
    * XML comments are stored in nodes named <xmlcomment>, unless comment ignoring is enabled via the flags.



  • scrontch schrieb:

    Doch:
    http://www.boost.org/doc/libs/1_42_0/doc/html/boost_propertytree/parsers.html#boost_propertytree.parsers.xml_parser
    * The attributes of an XML element are stored in the subkey <xmlattr>
    * XML comments are stored in nodes named <xmlcomment>, unless comment ignoring is enabled via the flags.

    Hm, danke, hab ich bisher immer übersehen. Besser wäre es aber gewesen, die Funktionalität gleich in rapidxml zu integrieren, nicht umsonst gibt es XPath (welches btw. PugiXML beherrscht!).
    Und das Feature ist rein auf den PropertyTree-XML-Teil beschränkt. Aber egal...


Anmelden zum Antworten