![]() |
XMLDOMDocument formatiert abspeichern
Hi Leute
Ich habe eine eigene XMLDOM Klasse geschrieben, die XML Dokumente lesen, bearbeiten und schreiben kann. Wenn ich nun ein XML Dokument lese und dort Knoten anfüge, werden diese beim Speichern nicht formatiert in das XML File geschrieben. Hier habe ich zwar eine Lösung:
Delphi-Quellcode:
Jedoch hat diese Lösung das Problem, wenn die Datei UTF-8 kodiert ist, dass im XML File die Umlaute nicht mehr UTF-8 konform gespeichert werden. Warum habe ich noch nicht rausgefunden. :wall:
function TBMDXMLDOMDocument.SaveToFile(const AFileName: String): Boolean;
function WriteDocumentToStream(const ADocument: IXMLDOMDocument2; const AStream: IStream; AEncoding: string = 'UTF-8'): Boolean; var lWriter: IMXWriter; lReader: IVBSAXXMLReader; begin Result := FALSE; try // Setze die Properties des XML writer - einschließlich BOM, XML Deklaration und encoding lWriter := CoMXXMLWriter60.Create; lWriter.byteOrderMark := True; lWriter.omitXMLDeclaration := False; lWriter.Indent := True; lWriter.encoding := AEncoding; // Setze den XML writer auf den SAX content handler. lReader := CoSAXXMLReader60.Create; lReader.contentHandler := lWriter as IVBSAXContentHandler; lReader.dtdHandler := lWriter as IVBSAXDTDHandler; lReader.errorHandler := lWriter as IVBSAXErrorHandler; lReader.putProperty('http://xml.org/sax/properties/lexical-handler', lWriter); lReader.putProperty('http://xml.org/sax/properties/declaration-handler', lWriter); // Setze den Writer auf den Stream lWriter.output := AStream; // Nun parse das DOM mit dem SAX handler, und rufe den XML Writer auf lReader.parse(ADocument); // Schreibe lWriter.flush; Result := TRUE; except end; end; var lStream: TFileStream; begin lStream := TFileStream.Create(AFilename, fmCreate or fmShareDenyWrite); try Result := WriteDocumentToStream(XMLDoc, TStreamAdapter.Create(lStream), Encoding); finally FreeAndNil(lStream); end; end; Rufe ich nur die Save Methode des XMLDOM Dokumentes auf, werden die Knoten unformatiert in das XML geschrieben und die Umlaute nicht mehr UTF-8 konform reingeschrieben. Dem Anschein nach sind die Umlaute verdoppelt im Code:
|
Re: XMLDOMDocument formatiert abspeichern
Was die Umlaute betrifft, ist die Antwort "einfach".
Beim Auslesen werden diese nicht decodiert (warum auch immer), sondern einfach nur als ANSI ausgelesen. Am Ende wird das Nichtdecodierte aber nach UTF-8 codiert, welches dann dein Ergebnis zur Folge hat. |
Re: XMLDOMDocument formatiert abspeichern
Hi
Danke für die schnelle Antwort. Was ich jedoch nicht verstehe ist, warum das nicht gemacht wird. Laut Doc wird bei LoadXML das Codierungsverfahren ausgelesen. Diese Methode rufe ich auf. Dann sollten ja die Werte richtig vorhanden sein. Oder muss man noch was aufrufen ?? |
Re: XMLDOMDocument formatiert abspeichern
Eventuell mußt du es selber behandeln?
Also im selber im contentHandler das Processor-Tag ( <?xml ) aufspüren, den Encoding-Parameter auswerten und dann das Encoding manuell setzen. :gruebel: |
Re: XMLDOMDocument formatiert abspeichern
Wegen dem formatieren, vielleicht hilft dir das ja?:
Zitat:
Das sollte dann die Einrückungen haben. |
AW: XMLDOMDocument formatiert abspeichern
Hi
Nach langem Rumspielen habe ich nun die Lösung. Das Problem war das Laden des XML Dokumentes selbst. Ich habe es mit der TFileStream und TStringStream Klasse gemacht. Diese verwendet jedoch implizit kein WideString, wodurch die Umlaute nicht mehr korrekt an das XMLDOM übergeben wurden. Nach der Änderung:
Code:
wurden die Umlaute korrekt angezeigt und auch beim Speichern gabe es keine Probleme mehr. :DlFileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite); try if Assigned(FOnBeginParse) then begin FOnBeginParse(self); end; try FLastParseErrorPos := Point(0, 0); FLastParseErrorCode := 0; GetXMLDoc.PreserveWhiteSpace := True; Result := GetXMLDoc.Load(TStreamAdapter.Create(lFileStream, soReference) as IStream); if not Result then begin FLastParseErrorPos := Point(GetXMLDoc.parseError.linepos - 1, GetXMLDoc.parseError.line - 2); FLastParseErrorCode := GetXMLDoc.parseError.ErrorCode; lStr := Format('Parse Error: %s (Line: %d, Pos: %d)', [Trim(GetXMLDoc.parseError.Reason), GetXMLDoc.parseError.Line-1, GetXMLDoc.parseError.LinePos-1]); if Assigned(FOnParseError) then begin FOnParseError(self, lStr, GetXMLDoc.parseError.Line-1, GetXMLDoc.parseError.LinePos-1); end; end; finally if Assigned(FOnEndParse) then begin FOnEndParse(self); end; end; finally FreeAndNil(lFileStream); end; Die Stylesheet Transformation werde ich heute ausprobieren. JEdoch vielen Dank für die Antworten. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz