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....


Log in to reply