TinyXML SmartWrapperClass, aber langsamer...
-
Hallo
Ich habe fpür ein Projekt eine XML-Lib gesucht und eine gute gefunden die klein ist(TinyXML: 88KB), keine Abhängigkeiten hat( wie MSXML) und kostenlos auch für den kommerziellen Einsatz ist.
Da bin ich auf TinyXML gekommen.
Aber der Syntax um Nodes hinzuzufügen und zu finden war mir viel zu lang.
Hier ein Beispiel aus dem Sample:TiXmlDocument doc( "demotest.xml" ); bool loadOkay = doc.LoadFile(); if ( !loadOkay ) { printf( "Could not load test file 'demotest.xml'. Error='%s'. Exiting.\n", doc.ErrorDesc() ); exit( 1 ); } printf( "** Demo doc read from disk: ** \n\n" ); doc.Print( stdout ); TiXmlNode* node = 0; TiXmlElement* todoElement = 0; TiXmlElement* itemElement = 0; // -------------------------------------------------------- // An example of changing existing attributes, and removing // an element from the document. // -------------------------------------------------------- // Get the "ToDo" element. // It is a child of the document, and can be selected by name. node = doc.FirstChild( "ToDo" ); assert( node ); todoElement = node->ToElement(); assert( todoElement ); // Going to the toy store is now our second priority... // So set the "priority" attribute of the first item in the list. node = todoElement->FirstChildElement(); // This skips the "PDA" comment. assert( node ); itemElement = node->ToElement(); assert( itemElement ); itemElement->SetAttribute( "priority", 2 );
Ich wollte was kürzerer und habe mal was implementiert, Beispiel für den Aufruf:
CString Test3 = "Test3_CString"; CMyTiXmlDocument doc( "./test.xml" ); if ( doc.Error() ) { TRACE( "Error in %s: %s\n", doc.Value(), doc.ErrorDesc() ); return false; } doc["RootElem"]["ChildA"]["Test1"] = 12346789; doc["RootElem"]["ChildA"]["Test2"] = "Test3"; doc["RootElem"]["ChildA"]["Test3"] = Test3; doc["RootElem"]["ChildB"]["ChildWithAttr"].Attribute("active","yes").Attribute("test","la").Attribute("D","ss") = "schriftlich"; doc["RootElem"]["ChildB"]["ChildChild"].Attribute("active","no").Attribute("test","testattr") = 33; doc.SaveFile();
Das ergibt folgende XML-Datei:
<?xml version="1.0" standalone="yes" ?> <RootElem> <ChildA> <Test1>12346789</Test1> <Test2>Test3</Test2> <Test3>Test3_CString</Test3> </ChildA> <ChildB> <ChildWithAttr active="yes" test="la" D="ss">schriftlich</ChildWithAttr> <ChildChild active="no" test="testattr">33</ChildChild> </ChildB> </RootElem>
Tolle Sache finde ich, es funktioniert auch wenn die Childs nochnicht erzeugt sind. Durch das Operatorenüberladen kann man alles mit CMyNode machen(im Beispiel int umwandeln) und für XML vorbereiten.
Das Problem ist nur die Performance(Test: Erzeugen 50 Children mit jeweils 20 Children):Raw API Calls gibt es 70ms
CMyClass gibt es 270ms (normal&inline)
Wenn das interessiert:
class CMyNode; class CMyTiXmlDocument; class CMyNode{ friend class CMyTiXmlDocument; public: CMyNode(){ thisNode = 0; UnterNode = NULL; } CMyNode(TiXmlElement * El){ thisNode = El; UnterNode = NULL; } CMyNode& operator =(const CMyNode& other) { // Copy-Construct if (this == &other) return *this; thisNode = other.thisNode; if(UnterNode != NULL) delete UnterNode; UnterNode = NULL; return *this; } CMyNode& operator = ( LPCSTR szValue ){ // Content-Assign( szString ) TiXmlText* pText = thisNode->FirstChild()->ToText(); if(pText == NULL){ TiXmlText text(szValue); thisNode->InsertEndChild(text); }else pText->SetValue(szValue); return *this; } CMyNode& operator = ( int iValue){ // Content-Assign (integer) char buff[16]; _itot( iValue, buff, 10 ); return operator = (buff); } operator TiXmlElement* () { return thisNode; } operator LPCSTR () { TiXmlText* pText = thisNode->FirstChild()->ToText(); return pText->Value(); } operator int () { TiXmlText* pText = thisNode->FirstChild()->ToText(); return _ttoi( pText->Value() ); } CMyNode& Attribute(LPCSTR name, LPCSTR value){ thisNode->SetAttribute(name, value); return *this; } CMyNode(const CMyNode& o){ // Copy-Construct, 2. way thisNode = o.thisNode; UnterNode = NULL; } ~CMyNode(){ if(UnterNode !=NULL) delete UnterNode; } CMyNode& operator [](LPCSTR szItemName) { TiXmlNode* node = thisNode->FirstChild(szItemName); if(node==NULL){ //Node micht da, also erzeugen TiXmlElement el( szItemName ); UnterNode = new CMyNode( thisNode->InsertEndChild( el)->ToElement() ); }else UnterNode = new CMyNode( node->ToElement() ); return *UnterNode; } protected: TiXmlElement* thisNode; private: CMyNode* UnterNode; }; class CMyTiXmlDocument : public TiXmlDocument { public: CMyTiXmlDocument() : TiXmlDocument(){ } CMyTiXmlDocument(const char *documentName) : TiXmlDocument(documentName){ } CMyNode& GetRoot(LPCSTR szItemName){ Node.thisNode = TiXmlDocument::RootElement(); if(Node.thisNode == NULL){ TiXmlDeclaration Decl("1.0", "","yes"); TiXmlDocument::InsertEndChild(Decl); TiXmlElement RootEl( szItemName); Node.thisNode = TiXmlDocument::InsertEndChild( RootEl )->ToElement(); } return Node; } CMyNode& operator [](LPCSTR szItemName) { return GetRoot(szItemName); } private: CMyNode Node; };
Was ist den hier die Bremse, wie soll ich das anders machen?
Danke für eure Hilfe
MFG
Tristan
-
Nur zu Info ich bin der Autor, komisch kein Login....