Bestimmte Bereiche aus XML-Datei entfernen

|mo|

Mitglied
Hallo!
Folgendes Problem:
Ich habe eine Reihe von XML-Dateien, aus denen ich gerne einige Tags entfernen würde (immer die gleichen Tags die raus sollen).
Hatte mir gedacht, ich mach das mit getline, klappt auch prinzipiell, allerdings nur, wenn ich nur ein Element entfernen will, bei mehreren gibts leider Probleme...
Kann jm. mal über den Code schauen und mir sagen, wo mein Denkfehler ist? Bin leider noch ziemlicher Neuling in Sachen C++
Code:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <conio.h>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
  ifstream datei;
  ofstream neuedatei;
  string zeile;
  datei.open("test.xml", ios::in);
  neuedatei.open("temp.xml", ios::out);
  bool gefunden = false;
  do
  {
    getline(datei,zeile);
    if(zeile.find( "<Datum>" ) !=string::npos)
      gefunden = true;
    if(!gefunden)
    neuedatei << zeile << endl;
    if(zeile.find( "</Datum>" ) !=string::npos)
      gefunden = false;
	getline(datei,zeile);
    if(zeile.find( "<Plakat>" ) !=string::npos)
      gefunden = true;
    if(!gefunden)
      neuedatei << zeile << endl;
    if(zeile.find( "</Plakat>" ) !=string::npos)
      gefunden = false;
  }while(!datei.eof());
  datei.close();
  neuedatei.close();
  return 0;
}
 
Hi.

Du kommst in deinem Code durcheinander welches Tag du gerade eingelesen hast bzw. welches Tag du erwartest.

Warum verwendest du nicht einen XSLT Prozessor oder wenigstens eine XML Bibliothek wie z.B. tinyxml oder LibAxl (http://sourceforge.net/project/showfiles.php?group_id=145682&package_id=188092&release_id=561046) - damit sollte das Problem viel leichter und verlässlicher (Was ist wenn die Elemente Attribute haben? Was wenn auf einer Zeile mehrer Tags stehen?) zu lösen sein.

Dann solltest du (fast) niemals die .eof() Methode von Streams verwenden und beim Einlesen immer prüfen ob das auch geklappt hat. Eine Datei liest man in C++ zeilenweise so ein:
C++:
while (getline(file, str)) {
  ...
}

Gruß
 
Nachdem ich auch von anderen Leuten gehört habe, ich solle einen XML-Parser wie tinyxml nutzen, habe ich mir diesen heruntergeladen... leider habe ich null Ahnung, wie selbiger funktioniert... :(
Ich habe das Gefühl, durch das Nutzen des Parsers wird mein Code nur um einiges komplizierter...
 
Nachdem ich auch von anderen Leuten gehört habe, ich solle einen XML-Parser wie tinyxml nutzen, habe ich mir diesen heruntergeladen... leider habe ich null Ahnung, wie selbiger funktioniert... :(
Ich habe das Gefühl, durch das Nutzen des Parsers wird mein Code nur um einiges komplizierter...
Das Gegenteil ist der Fall. Folgender Code entfernt aus einem XML Dokument die Datum und Plakat Elemente:
C++:
#include "tinyxml.h"

using namespace std;

void removeTags(TiXmlElement* parent) {
  if (parent->ValueStr() == "Datum" ||
      parent->ValueStr() == "Plakat") {

    parent->Parent()->RemoveChild(parent);
  } else {

    TiXmlNode* child  = 0;
  
    while(child = parent->IterateChildren(child)) {
      TiXmlElement* p = child->ToElement();
      
      if (p != 0) removeTags(p);
    }
  }
}

int main() {
  TiXmlDocument doc( "test.xml" );
  
  if (doc.LoadFile()) {
    removeTags(doc.RootElement());

    doc.SaveFile("test2.xml");
  }
}
Gruß
 
error C2039: 'ValueStr': Ist kein Element von 'TiXmlElement'
Siehe Deklaration von 'TiXmlElement'

?
Etwas mehr Informationen wären sehr hilfreich. Was hast du installiert (Version, Dateiname etc.) und wie?

Vermutlich hast du ohne STL Unterstützung kompiliert?

Du kannst den Vergleich auch mit der strcmp C Funktion machen:
C++:
#include <cstring>
...
if (strcmp(parent->Value(), "Datum") == 0 ||
    strcmp(parent->Value(), "Plakat") == 0) {
  ...
}
Gruß
 
Sorry für die spärliche Angabe von Informationen im vorherigen Beitrag, bin nur etwas frustriert zur Zeit...
Also en tu ich mit Visual C++ 2005, installiert habe ich tinyxml2.5.3 und in mein Projekt die tinystr.h und die tinyxml.h zu den headerdateien hinzugefügt.
Mit deiner letzten Änderung bekomme ich jetzt ganz komische Fehler...:

test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: bool __thiscall TiXmlNode::RemoveChild(class TiXmlNode *)" (?RemoveChild@TiXmlNode@@QAE_NPAV1@@Z)" in Funktion ""void __cdecl removeTags(class TiXmlElement *)" (?removeTags@@YAXPAVTiXmlElement@@@Z)".
test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: class TiXmlNode const * __thiscall TiXmlNode::IterateChildren(class TiXmlNode const *)const " (?IterateChildren@TiXmlNode@@QBEPBV1@PBV1@@Z)" in Funktion ""public: class TiXmlNode * __thiscall TiXmlNode::IterateChildren(class TiXmlNode const *)" (?IterateChildren@TiXmlNode@@QAEPAV1@PBV1@@Z)".
test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: bool __thiscall TiXmlDocument::SaveFile(char const *)const " (?SaveFile@TiXmlDocument@@QBE_NPBD@Z)" in Funktion "_main".
test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: bool __thiscall TiXmlDocument::LoadFile(enum TiXmlEncoding)" (?LoadFile@TiXmlDocument@@QAE_NW4TiXmlEncoding@@@Z)" in Funktion "_main".
test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall TiXmlDocument::TiXmlDocument(char const *)" (0TiXmlDocument@@QAE@PBD@Z)" in Funktion "_main".
test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: virtual __thiscall TiXmlNode::~TiXmlNode(void)" (1TiXmlNode@@UAE@XZ)" in Funktion ""public: virtual __thiscall TiXmlDocument::~TiXmlDocument(void)" (1TiXmlDocument@@UAE@XZ)".
test.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: virtual void __thiscall TiXmlDocument::Print(struct _iobuf *,int)const " (?Print@TiXmlDocument@@UBEXPAU_iobuf@@H@Z)".
test.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: virtual char const * __thiscall TiXmlDocument::Parse(char const *,class TiXmlParsingData *,enum TiXmlEncoding)" (?Parse@TiXmlDocument@@UAEPBDPBDPAVTiXmlParsingData@@W4TiXmlEncoding@@@Z)".
test.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""protected: virtual class TiXmlNode * __thiscall TiXmlDocument::Clone(void)const " (?Clone@TiXmlDocument@@MBEPAVTiXmlNode@@XZ)".
test.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: virtual bool __thiscall TiXmlDocument::Accept(class TiXmlVisitor *)const " (?Accept@TiXmlDocument@@UBE_NPAVTiXmlVisitor@@@Z)".
test.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""private: static struct TiXmlString::Rep TiXmlString::nullrep_" (?nullrep_@TiXmlString@@0URep@1@A)".
test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: class TiXmlElement const * __thiscall TiXmlNode::FirstChildElement(void)const " (?FirstChildElement@TiXmlNode@@QBEPBVTiXmlElement@@XZ)" in Funktion ""public: class TiXmlElement * __thiscall TiXmlNode::FirstChildElement(void)" (?FirstChildElement@TiXmlNode@@QAEPAVTiXmlElement@@XZ)".
 
Sorry für die spärliche Angabe von Informationen im vorherigen Beitrag, bin nur etwas frustriert zur Zeit...
Also en tu ich mit Visual C++ 2005, installiert habe ich tinyxml2.5.3 und in mein Projekt die tinystr.h und die tinyxml.h zu den headerdateien hinzugefügt.
Das reicht nicht aus die Headerdateien einzufügen. Du mußt auch die .cc Dateien ins Projekt mit einbinden damit die mit kompiliert werden.

Generell ist es auch eine gute Idee erstmal die Dokumentation zu lesen! :rtfm:

Gruß
 
Zurück