XMLReader neustarten (Visual C++/CLI)

B.XP

Urgestein
Thread Starter
Mitglied seit
06.07.2006
Beiträge
6.899
Ort
Bayern
Hey,

ich habe gerade ein vermutlich relativ simples Problem, komme aber nicht auf die Lösung. MSDN/Google/Bing liefern mir dazu auch keine brauchbaren Antworten.

Die Situation:
Ich habe eine Bedienoberfläche und eine Klasse mit der ich die XML-Dateien handeln kann; Mit der Oberfläche lade ich über einen "Öffnen"-Dialog einen (File)Stream, den ich einer Lademethode der Klasse übergeben kann - funktioniert.

Code:
bool cxml::file_set(Stream^ file){
	if(file == nullptr)
		return false;
	if(FileToPlay != nullptr)
		FileToPlay->Close();
	try{
		FileToPlay = file;
		xreader = XmlReader::Create(FileToPlay, xreader_settings);
		if(xreader != nullptr){
			xreader->MoveToContent();
			addlogtext(xreader->Name);
			file_loaded = true;
			return true;
		} else	
			addlogtext("xreader == null");
	}catch(Exception^ e){
		addlogtext(e->ToString());
	}
	file_loaded = false;
	return false;
}

Nun will ich das File loopen. Da der XMLreader eben forward-read-only ist, muss ich den Stream neu laden...nur bekomm ich beim Versuch zu lesen eine Exception. Der Code sieht im wesentlichen genauso aus, nur wird anstelle von FileToPlay mein xreader(mein XmlReader) geschlossen (xreader->close()). Stream^ FileToPlay ist ein Klassenelement.

Hat irgendjemand eine Idee wo der Fehler liegen könnte?
 
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Ja, wäre nützlich...;)

Code:
System.Xml.XmlException: Ungültige Daten auf Stammebene. Zeile 1, Position 1.
   bei System.Xml.XmlTextReaderImpl.Throw(Exception e)
   bei System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
   bei System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
   bei System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   bei System.Xml.XmlTextReaderImpl.Read()
   bei System.Xml.XmlReader.MoveToContent()
   bei cmuxml.file_reset(Boolean ) in [pfad]\xml.cpp:Zeile 82.

Zeile 82 ist
Code:
xreader->MoveToContent();

Die XML-Datei beginnt wie folgt (IE-Anzeige...):
Code:
<?xml version="1.0" encoding="UTF-8" ?> 
- <BLACKBOX_TEST>
- <testsuite id="Init">
 
Wie gesagt, hab ich Google schon gefragt, auch genau danach. ;)

Die Leute bekommen zwar auch die Exception, wird aber durch andere Methoden/vorgehensweisen ausgelöst. Besonders beliebt sind grundsätzliche Ladefehler oder probleme in der Webanwendung.
Zusätzlich hat sich die XmlReader-Thematik vergleichen mit vorherigen .Net-Versionen etwas geändert, z.B. weg von den abgeleiteten XmlTextReadern zum XmlReader mit "Create"...!
Bei mir lässt sich der Stream ja erst laden, nur beim Versuch das ohne neuen FileDialog zu wiederholen schlagen die XmlReader-Read-Anweisungen (somit auch MoveToContent) fehl.
 
100% Sicher bin ich mir nicht aber ich habe eine Vermutung. Müsstest du mal mit dem debugger durchgehen.

Du arbeitest da ja mit Zeigern. Genauergesagt hast du 2 Zeiger, die auf die gleiche Datei zeigen. Das erste was auffällig ist, ist das du unter bestimmten Bedingungen (2. IF Abfrage) die Datei schließt. Das würde sich eventuell auch auf den anderen Zeiger auswirken. Je nachdem ob sie in diesem Moment auf die selber Datei zeigen oder nicht. Das erklärt zwar nicht dein Problem aber wenn du irgendwann mal einen entsprechende Fehlermeldung bekommst, weißt du schonmal woran es liegen könnte.

Was ich jetzt nicht genau weiß ist ob du mit dem selben Stream gleichzeitig 2 Zugriffe machen kannst. Wenn ich dich richtig verstanden habe, hast du die XML Datei bereits geöffnet und geladen. Du willst sie nun erneut laden. Da du ja wunderschön mit Zeigern arbeitest, liegt es nahe, dass du versuchst das selbe Objekt irgendwie erneut zu verwenden obwohl es bereits verwendet wird.

Naja mein XML und C++ liegt schon etwas zurück. Ich weiß nur noch, dass man mit Zeigern viele schöne Sachen machen kann und sie eine häufige Fehlerquelle sind. Genaueres kann ich aber leider nicht sagen.
 
Danke erstmal, meine Vermutung ist, dass der Stream nicht richtig gehandelt wird, ergo ich mir den Pfad merken muss, damit ich (mit entsprechender Absicherung) die Datei später ohne Nutzereingabe neu laden kann. Diesen Mechanismus brauche ich sowieso, da ich gerade noch die Anforderung bekommen habe eine "Playlist" für mehrere XML-Dateien zu bauen...

Das mit der zweiten IF-Abfrage im Laden-Teil habe ich garnicht bemerkt, 4 Augen sehen mehr als 2... :bigok:

In der Reload-Funktion schließe ich in der 2. IF-Abfrage den XMLReader, inwiefern sich das auf den genutzten Filestream auswirkt ist aber undokumentiert. Die Intention ist, dass ich den Reader schließe, um besagten Doppelzugriff auf den selben Stream zu verhindern. Im nächsten Schritt soll der Reader mittels Create neu initialisiert werden, das funktioniert* sogar auch noch, aber beim Lesezugriff nicht mehr...

*im Sinne von: Keine Exceptions, keine NULL-Rückgabe...

C++/CLI ist für mich kein Neuland, XML aber schon...bislang wurde der Blackboxtest mittels Kommandozeilenprogramm (textbasierter "XML-Parser", vor meiner Zeit) durchgeführt, mittlerweile braucht's ein grafisches Frontend, da die Konsole die Unmengen an Daten nicht mehr verträgt, und das XML-File auch anders ausgewertet wird.

Durch Zufall bin ich jetzt auf die Lösung gestoßen, als ich nach etwas anderem gesucht habe:
FileToPlay->Seek(0, SeekOrigin::Begin);
xreader = XmlReader::Create(FileToPlay, xreader_settings);
Der Stream wird scheinbar durch den XmlReader "verschoben", und durch das muss zurückgesetzt werden bevor man ihn nochmals nutzt.
 
Zuletzt bearbeitet:
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh