LoadXML vs. ReadFile und CatchXML

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
derRaab
Beiträge: 71
Registriert: 30.12.2004 13:45
Wohnort: Berlin
Kontaktdaten:

LoadXML vs. ReadFile und CatchXML

Beitrag von derRaab »

Hallo Leute,

ich sitze jetzt schon ein paar Stunden dran und kapiere nicht ganz was ich falsch mache. Habe jetzt schon unzählige Versionen ausprobiert und bin nie zu einem Ergebnis gekommen.

Das Problem in Kürze:

Ich habe eine kleine Applikation die aus einer Unmenge an bestehenden XML-Dateien eine neue Struktur zusammen parst. Das funktioniert soweit einwandfrei, nur manche XML Dateien sind nicht valide, vor allem wird da öfter mal   an stellen verwendet, wo man das eigentlich gar nicht darf.

Die XML Lib motzt entsprechend und liefert (wenn ich die XML Datei mit LoadXML lade) #PB_XML_UndefinedEntity. Das möchte ich gerne abfangen indem ich einfach die Datei als String lade und so evtl. mittels String Funktionen manuell das   rausschmeissen kann.

Aber irgendwie krieg ich das ums Verrecken nicht hin.

Hier mal eine von vielen Versionen:

Code: Alles auswählen

Procedure LoadStatusValidatedXML( filePath$ )

	Protected file = ReadFile( #PB_Any, filePath$ )
	
	If file
	
		Protected text$
		
		While Eof( file ) = 0
		
			text$ = text$ + ReadString( file )
		
		Wend
		
		Protected xml = CatchXML( #PB_Any, @text$, Len( text$ ) )
		
		Protected status = XMLStatus( xml )
		
		Debug "XML status : " + Str( status )
		
		If status = #PB_XML_UndefinedEntity
		
			; do something and recreate the xml!
		
		EndIf
		
		ProcedureReturn xml
		
	EndIf
	
EndProcedure
Wenn ich das aber lade, dann motzt die Lib ( #PB_XML_IncorrectEncoding ), was aber defakto nicht der Fall ist.

Hat evtl. jemand einen Tipp für mich? Ich würde mich sehr freuen!
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: LoadXML vs. ReadFile und CatchXML

Beitrag von Kiffi »

Hallo derRaab,

welches Encoding hat denn die Datei? Kannst Du das Teil
mal zum Download bereitstellen?

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
derRaab
Beiträge: 71
Registriert: 30.12.2004 13:45
Wohnort: Berlin
Kontaktdaten:

Beitrag von derRaab »

Hi Kiffi,

das Encoding ist definitiv UTF-8, allerdings ohne UTF-8 BOM (was auch immer das bedeutet ;) ).

Aber eigentlich müsste mein Skript oben doch fehlerfrei sein, oder?
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

derRaab hat geschrieben:Aber eigentlich müsste mein Skript oben doch fehlerfrei sein, oder?
kann ich hier von der Ferne aus (ohne Beispiel-XML, um die ich Dich gebeten
habe) nicht beurteilen.

Du solltest folgende Dinge checken:

* Beinhalten Deine zu ladenden Dateien XML-Deklarationen (<?xml version...)?
Wenn ja, dann test mal, ob es hilft, diese beim Laden zu überspringen.

* Versuch mal, die UTF-8-Dateien explizit als solche auszulesen:

Code: Alles auswählen

      text$ + ReadString( File , #PB_UTF8 )
Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
derRaab
Beiträge: 71
Registriert: 30.12.2004 13:45
Wohnort: Berlin
Kontaktdaten:

Beitrag von derRaab »

Hallo Kiffi,

wie gesagt, am XML liegt das nicht, da ist das alles schon in Ordnung so. Wenn ich statt mit ReadString jede einzelne Zeile einfach mit ReadData den kompletten Inhalt lade, dann geht das soweit einwandfrei.

Sprich das XML kann korrekt mit CatchXML initialisiert werden.

Wenn ich dann aber, um die falschen Entities zu ersetzen, den Speicher in eine Variable auslese, bekomme ich danach wieder die Meldung, dass das Encoding nicht passt.

Ich muss mir jetzt also einen Weg suchen, wie ich die Daten direkt an Ort und Stelle im Speicher bearbeiten kann. So recht gefunden habe ich da aber noch nix.

Wie ersetzt man denn im UTF-8 bereich einzelne Zeichen im Speicher? Da können die Zeichen ja auch mal 2 bytes lang sein, oder?

Hier der Code, der bis dahin korrekt funktioniert:

Code: Alles auswählen

Procedure LoadStatusValidatedXML( filePath$ )

	Protected file = ReadFile( #PB_Any, filePath$ )
	
	If file
	
		Protected length = Lof( file )
	
		Protected *MemoryID = AllocateMemory( length )
		
		If *MemoryID
		
			Protected bytes = ReadData( file, *MemoryID, length )
			
			Protected xml = CatchXML( #PB_Any, *MemoryID, bytes )
			
			Protected status = XMLStatus( xml )
			
			If status <> 0
			
				Debug "XML status : " + Str( status )
			
			EndIf
			
			If status = #PB_XML_UndefinedEntity

; Ab hier geht das nicht mehr korrekt:
			
				Protected text$ = PeekS( *MemoryID, bytes, #PB_UTF8 )
				
				text$ = ReplaceString( text$, "&nbsp;", " " )
				
				FreeMemory( *MemoryID )
				
				FreeXML( xml )
				
				xml = CatchXML( #PB_Any, @text$, Len( text$ ) )
				
				Debug xml 
				
				Debug "XML status : " + Str( XMLStatus( xml ) )
; Der Status ist dann 19 ( #PB_XML_UnknownEncoding )				
			EndIf
			
			ProcedureReturn xml
		
		EndIf
	
	EndIf
	
EndProcedure
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

derRaab hat geschrieben:wie gesagt, am XML liegt das nicht, da ist das alles schon in Ordnung so.
das habe ich auch mit keiner Silbe bezweifelt... ;-)

Wie bereits erwähnt: für mich persönlich wäre es leichter, etwas
konkretes zum Thema zu schreiben, wenn ich über ein, zwei
Beispiel-XML-Dateien verfügen würde.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
derRaab
Beiträge: 71
Registriert: 30.12.2004 13:45
Wohnort: Berlin
Kontaktdaten:

Beitrag von derRaab »

Na das hab ich ja soweit zum Laufen bekommen (ReadData statt ReadString), allerdings blick ich noch nicht so ganz durch, wie ich den String direkt im Speicher verarbeite. Aber da frickel ich mich noch rein. :)
Antworten