Immernoch Probleme mit TinyXML
-
Hallo,
ich habe mehrere Einträge in meiner XML Datei in der Form:
<root> <Icon Name="1.txt" X="-2.35" Y="1.56" Z="-5.5" /> <Icon Name="1717_arbeitsdateien" X="-2.35" Y="1.26" Z="-5.5" /> ... </root>Eine Methode soll jetzt über alle Elemente iterieren, falls ein Element mit dem übergebenen Namen übereinstimmt sollen die X,Y,Z Werte aktualisiert werden.
Die Methode:
BOOL updateElement(TiXmlElement element) { // Get the config file TiXmlDocument doc( (char*)positionDataFile.c_str() ); // Try loading config file if ( !doc.LoadFile() ) cout << "could not read file"; BOOL result = false; TiXmlNode * iNode = doc.FirstChild( "root" ); TiXmlNode * itemNode = iNode->FirstChild( "Icon" ); if( iNode != NULL ) { while( itemNode != NULL ) { string temp1 = itemNode->ToElement()->Attribute("Name"); string temp2 = element.ToElement()->Attribute("Name"); if(strcmp(temp1.c_str(), temp2.c_str()) == 0) { itemNode->ToElement()->SetAttribute("X", element.ToElement()->Attribute("X")); itemNode->ToElement()->SetAttribute("Y", element.ToElement()->Attribute("Y")); itemNode->ToElement()->SetAttribute("Z", element.ToElement()->Attribute("Z")); cout << "Setting Z of element: " << temp2 << "to: " << element.ToElement()->Attribute("Z") << "\n"; result = true; break; } itemNode = iNode->IterateChildren( "Icon", itemNode ); } } doc.SaveFile(); return result; }Der Aufruf:
// Set attributes for an Element. wert.SetAttribute("Name", name); wert.SetAttribute("X", xString.c_str()); wert.SetAttribute("Y", yString.c_str()); wert.SetAttribute("Z", zString.c_str()); // Get the root Element root = doc.FirstChildElement("root"); if (root) { // This checks if the node wert is already in the .xml file // If it is inside, the values will be updated. if(!updateElement(wert)) root->InsertEndChild(wert); }Das Problem: das Aktualisieren klappt nicht. Dh die updateElement Methode hat wohl noch einen Bug, den ich aber nicht finde. Hat jemand eine Idee?
Gruß
Alex
-
if(strcmp(temp1.c_str(), temp2.c_str()) == 0)Wieso nicht einfach
if(temp1 == temp2)?
-
filth schrieb:
Das Problem: das Aktualisieren klappt nicht. Dh die updateElement Methode hat wohl noch einen Bug, den ich aber nicht finde. Hat jemand eine Idee?
Tausende ...
Aber zuerst einmal:
TiXmlDocument doc( (char*)positionDataFile.c_str() );Was hatte ich gesagt? Böse! Aus! :p
Zu deinem Problem:
Hast du schon mal mit C++ gearbeitet und/oder mal die TinyXML Dokumentation durchgelesen? Dein Vorgehen ist zum Scheitern verdammt
Ich stelle wohl am einfachsten ein paar Fragen:
- Wieso öffnest du in der Funktion das Dokument erneut und speicherst es am Ende wieder? Wieso übergibst du nicht das Dokument, welches du bereits geöffnet hast per Referenz? Da wird am Ende sicher das falsche Dokument gespeichert.
- Wieso verwendest duBOOL, stattbool? Zu viel Windowsprogrammierung gehabt?
- Wieso übergibst du einTiXmlElementObjekt und nimmst es intern dann wieder auseinander. Wieso nicht gleich die Parameter übergeben, am besten per const-Referenz?
- Wieso vergleichst du diestd::stringnicht direkt miteinander, sondern mühsam über C-Funktionen?
- Wieso iterierst du so kompliziert durch deine Nodes und zum Beispiel nicht gleich über die Elemente und ihren Geschwistern?
- Wieso fügst du das Element nicht gleich in der Funktion ein? Dann kannst du dir den Rückgabewert ersparen!
- Wieso verwendest du eineBOOL resultVariable? Wieso da mal wiederBOOLstattboolund wieso nicht in der Funktion statt desbreaklieber gleich einreturn true?
- Rufst du diese updateElement Funktion mehrmals hintereinander auf? Dann wäre das noch extrem ineffizient!Das wäre es soweit einmal von mir. Mehr fällt mir jetzt grad nicht ein an Fragen. Ich persönlich würde alles in deinem Code umschreiben

Grüssli
-
Hi,
danke für die Tipps. Nun funktioniert es.
Habe es so gelöst:
bool updateElement(TiXmlElement element, TiXmlDocument &doc) { bool result = false; TiXmlNode * iNode = doc.FirstChild( "root" ); TiXmlNode * itemNode = iNode->FirstChild( "Icon" ); if( iNode != NULL ) { while( itemNode != NULL ) { string temp1 = itemNode->ToElement()->Attribute("Name"); string temp2 = element.ToElement()->Attribute("Name"); // If the names are equal set the values to the passed values if(strcmp(temp1.c_str(), temp2.c_str()) == 0) { itemNode->ToElement()->SetAttribute("X", element.ToElement()->Attribute("X")); itemNode->ToElement()->SetAttribute("Y", element.ToElement()->Attribute("Y")); itemNode->ToElement()->SetAttribute("Z", element.ToElement()->Attribute("Z")); result = true; } itemNode = iNode->IterateChildren( "Icon", itemNode ); } } return result; }
-
Du hast sicher nochmals die Hälfe der Tipps ausgelassen, deshalb konnte ich jetzt nicht anders ...
bool updateElement(TiXmlDocument& doc, std::string const& name, std::string const& valueX, std::string const& valueY, std::string const& valueZ) { TiXmlElement* element = doc.FirstChildElement("root"); if(element) { element = element->FirstChildElement("Icon"); } char const* attrName; while(0 != element) { attrName = element->Attribute("Name"); // If the names are equal set the values to the passed values if(attrName != 0 && name == attrName) { element->SetAttribute("X", valueX); element->SetAttribute("Y", valueY); element->SetAttribute("Z", valueZ); return true; } element = element->NextSiblingElement("Icon"); } return false; }Grüssli
-
Naa gut, Danke!
