tinyxml - triviales problem?!
-
Hallo liebe c++ experten,
ich hab heute schon den ganzen tag mit der suche nach einem problem verbracht,
was auf den ersten blick recht simpel zu sein scheint, aber ich hab überhaupt nichts dazu gefunden - deswegen jetzt hier ein thread dazu:Die Idee ist folgende: ich hab ein Xml-file beliebiger "Tiefe".
es interessiert mich eigentlich nicht, wie das Xml-file aufgebaut ist,
sondern ich weiß, dass es "valid" ist und alles andere ist mir egal.Jetzt möchte ich mit "Tinyxml" , die Xml-datei einlesen und anschließend
alles was sich im "root-element" der datei befindet
( andere knoten,attribute, text etc ...) einfach in einen neuen mit "tinyxml" erstellten element-baum mitLinkEndChild(...)einhängen!
hier mein c++ -code zum testen:
buildTree()erzeugt einfach nur das xml-dokument, das später eingehängt werden soll.
appendTree()erzeugt einen neuen "baum", in den dann das rootelement mit inhalt eingehängt werden soll
ich schaffe es bis jetzt nur, das dokument einzulesen und den namen des root-elements einzuhängen,
was muss ich machen, dass alles was im rootelement drin steht eingehängt wird?/* * Test.cpp * * Created on: 09.04.2010 * Author: blulining */ #include "tinyxml.h" #include "tinystr.h" #include <vector> #include <sstream> #include <iostream> using namespace std; void appendTree() { TiXmlDocument doc; doc.LoadFile("TestFile.xml"); doc.Print(); TiXmlElement* rootElement = doc.RootElement(); TiXmlDocument newDocument; TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "", ""); TiXmlElement * element = new TiXmlElement("NewRoot"); newDocument.LinkEndChild(decl); newDocument.LinkEndChild(element); element->LinkEndChild(new TiXmlElement(rootElement->Value())); newDocument.SaveFile("NeuesFile.xml"); } void buildTree() { TiXmlDocument doc; TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "", ""); TiXmlElement * element = new TiXmlElement("root"); doc.LinkEndChild(decl); doc.LinkEndChild(element); vector<TiXmlElement*> children; string name; for (int i = 0; i < 3; i++) { string s = "child"; stringstream out; out << i + 1; s += out.str(); children.push_back(new TiXmlElement(s.c_str())); element->LinkEndChild(children.back()); string name2; for (int j = 0; j < 2; j++) { string s2 = "grandchild"; stringstream out2; out2 << j + 1; s2 += out2.str(); TiXmlElement* grandchild=new TiXmlElement(s2.c_str()); children.back()->LinkEndChild(grandchild); grandchild->LinkEndChild(new TiXmlText(out2.str().c_str())); } } doc.SaveFile("TestFile.xml"); } int main() { buildTree(); appendTree(); return 0; }vergesst nicht nach dem ausführen von
main()F5 zu drücken, sonst werden die neu erstellten xml-files nicht angezeigt!
Danke im vor raus für eure hilfe!
best regards
blulining
-
nach ewig viel rumprobieren hab ichs jetz endlich hinbekommen...
so funktionierts:void appendTree() { TiXmlDocument doc; doc.LoadFile("TestFile.xml"); TiXmlElement* rootElement = doc.RootElement(); TiXmlDocument newDocument; TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "", ""); TiXmlElement * element = new TiXmlElement("NewRoot"); newDocument.LinkEndChild(decl); newDocument.LinkEndChild(element); element->LinkEndChild(rootElement->Clone()); newDocument.SaveFile("NeuesFile.xml"); }die entscheidende änderung liegt in
element->LinkEndChild(rootElement->Clone());ohne das Clone() gibt es immer segmentation-violation fehler etc...
-
hallo ich habe das gleiche Problem wie der Vorposter nur will ich nicht die ganze Datei kopieren sondern nur die ersten childs in seperate Dateien machen.
bool chopper::element_to_document(TiXmlElement * element,const char*name) { if(element ==0) { qDebug()<< element; return false ; } else { TiXmlDocument * new_doku; TiXmlElement * basis = new TiXmlElement("NewRoot"); basis->LinkEndChild(element); if (new_doku->SaveFile(name)) { return true; } }und der aufruf
void chopper::make_small_xml(TiXmlDocument doku) { //doc.Parse() TiXmlHandle docHandle(&doku); TiXmlElement* projectElement; int i = 1; projectElement = docHandle.FirstChildElement().Element(); TiXmlHandle projectHandle(projectElement); // ---------------------------------------------------------------------------------------- for(TiXmlElement* operatorElement = projectHandle.FirstChild("operator").ToElement(); operatorElement; operatorElement = operatorElement->NextSiblingElement("operator") ) { std::string operator_name; if(operatorElement->Attribute("name") != 0) { operator_name = operatorElement->Attribute("name"); QString halter = QString::fromStdString(operator_name); qDebug()<<"Name:"<< halter; if(this->element_to_document(projectElement,"Test")==true) { qDebug()<<"Spalten sollte funktionieren ! "; } }der Fehler ist : Shell_Haddop: tinyXML/tinyxml.cpp:188: TiXmlNode* TiXmlNode::LinkEndChild(TiXmlNode*): Assertion `node->parent == 0 || node->parent == this' failed.
Das Programm ist abgestürzt.
ich komme nicht drauf was falsch ist ....
-
hi mount /dev0,
ich glaub das ist die gleiche fehlermeldung die ich auch hatte damals...
du verwendest nirgends ein Clone() ...
versuch das mal einzubauen, vll gehts dann!
ich würds entweder mal so versuchen:else { TiXmlDocument * new_doku; TiXmlElement * basis = new TiXmlElement("NewRoot"); basis->LinkEndChild(element->Clone()); if (new_doku->SaveFile(name)) { return true; } }oder wenn das nicht funktioniert würd ich das jeweilige element schon in der aufrufmethode clonen....
abgesehen davon willst du doch bestimmt immer den namen des jeweiligen elements als dateinamen oder?
weil hier speicherst du s ja immer unter dem gleichen namen ab ("Test"):this->element_to_document(projectElement,"Test")jepp hoffe das hilft irgendwie weiter... :-?
-
so ich hab mich an das Vorprojekt gehalten, jetzt fehlt noch der Iterator °°
bool chopper::chopsui(QByteArray name_file,QByteArray name_data) { //------------------------------------------------------------------------------ int i = 1; TiXmlDocument doku = this->load_file(name_file); TiXmlElement* rootElement = doku.RootElement()->FirstChildElement(); TiXmlHandle docHandle(&doku); TiXmlElement * projectElement = docHandle.FirstChildElement().Element(); TiXmlHandle projectHandle(projectElement); // HIER SOLLTE DER ITERATOR KOMMEN //----------------------------------------------------------------------------- TiXmlDocument newDocument; TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "", ""); TiXmlElement * element = new TiXmlElement("project"); newDocument.LinkEndChild(decl); newDocument.LinkEndChild(element); element->LinkEndChild(rootElement->Clone()); QString name = this->create_name(name_data,i); i++; qDebug()<<name; newDocument.SaveFile(name.toAscii()); // HIER SOLLTE ER AUFHÖREN }
-
final und geht

bool chopper::chopsui(QByteArray name_file,QByteArray name_data) { int i = 1; TiXmlDocument doku = this->load_file(name_file); TiXmlNode * iNode = doku.FirstChild( "project" ); // ======================================================================================= if( iNode != NULL ) { for( TiXmlNode * itemNode = iNode->FirstChild( "operator" ); itemNode != NULL; itemNode = iNode->IterateChildren( "operator", itemNode ) ) { TiXmlDocument newDocument; TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "", ""); TiXmlElement * element = new TiXmlElement("project"); newDocument.LinkEndChild(decl); newDocument.LinkEndChild(element); //element->LinkEndChild(rootElement->Clone()); element->LinkEndChild(itemNode->Clone()); QString name = this->create_name(name_data,i); i++; if(newDocument.SaveFile(name.toAscii())) { return true; } else { return false; } } } return false; }