When an XMLDOMDocument saves itself, how can i get it to include the XML Declaration, e.g.:
Here's the same thing in Delphi:
//writes the document to the WideString as UTF-16 (since it's a WideString)
class function TXMLHelper.WriteDocumentToString(
const Document60: DOMDocument60): WideString;
var
writer: IMXWriter;
reader: IVBSAXXMLReader;
bstr: OleVariant;
begin
{
From http://support.microsoft.com/kb/275883
INFO: XML Encoding and DOM Interface Methods
MSXML has native support for the following encodings:
UTF-8
UTF-16
UCS-2
UCS-4
ISO-10646-UCS-2
UNICODE-1-1-UTF-8
UNICODE-2-0-UTF-16
UNICODE-2-0-UTF-8
It also recognizes (internally using the WideCharToMultibyte
API function for mappings) the following encodings:
US-ASCII
ISO-8859-1
ISO-8859-2
ISO-8859-3
ISO-8859-4
ISO-8859-5
ISO-8859-6
ISO-8859-7
ISO-8859-8
ISO-8859-9
WINDOWS-1250
WINDOWS-1251
WINDOWS-1252
WINDOWS-1253
WINDOWS-1254
WINDOWS-1255
WINDOWS-1256
WINDOWS-1257
WINDOWS-1258
}
if Document60 = nil then
raise Exception.Create('TXMLHelper.WriteDocument: Document60 cannot be nil');
// Set properties on the XML writer
// - including BOM, XML declaration and encoding
writer := CoMXXMLWriter60.Create;
writer.byteOrderMark := False; //Don't write the BOM. Has no effect for BSTR output, but still: we don't want it. Determines whether to write the Byte Order Mark (BOM). The byteOrderMark property has no effect for BSTR or DOM output. (Default True)
writer.omitXMLDeclaration := False; //Don't skip the xml declaration. Forces the IMXWriter to skip the XML declaration. Useful for creating document fragments. (Default False)
// writer.encoding := 'UTF-8'; //Sets and gets encoding for the output. (Default "UTF-16")
writer.indent := True; //Sets whether to indent output. (Default False)
writer.standalone := True; //Sets the value of the standalone attribute in the XML declaration to "yes" or "no".
// Set the XML writer to the SAX content handler.
reader := CoSAXXMLReader60.Create;
reader.contentHandler := writer as IVBSAXContentHandler;
reader.dtdHandler := writer as IVBSAXDTDHandler;
reader.errorHandler := writer as IVBSAXErrorHandler;
reader.putProperty('http://xml.org/sax/properties/lexical-handler', writer);
reader.putProperty('http://xml.org/sax/properties/declaration-handler', writer);
// Now pass the DOM through the SAX handler, and it will call the writer
reader.parse(Document60);
// Let the writer do its thing
bstr := writer.output;
Result := bstr;
end;
And a version of writing to a stream:
class procedure TXMLHelper.WriteDocumentToStream(const Document60: DOMDocument60; const stream: IStream; Encoding: string);
var
writer: IMXWriter;
reader: IVBSAXXMLReader;
begin
{
From http://support.microsoft.com/kb/275883
INFO: XML Encoding and DOM Interface Methods
MSXML has native support for the following encodings:
UTF-8
UTF-16
UCS-2
UCS-4
ISO-10646-UCS-2
UNICODE-1-1-UTF-8
UNICODE-2-0-UTF-16
UNICODE-2-0-UTF-8
It also recognizes (internally using the WideCharToMultibyte API function for mappings) the following encodings:
US-ASCII
ISO-8859-1
ISO-8859-2
ISO-8859-3
ISO-8859-4
ISO-8859-5
ISO-8859-6
ISO-8859-7
ISO-8859-8
ISO-8859-9
WINDOWS-1250
WINDOWS-1251
WINDOWS-1252
WINDOWS-1253
WINDOWS-1254
WINDOWS-1255
WINDOWS-1256
WINDOWS-1257
WINDOWS-1258
}
if Document60 = nil then
raise Exception.Create('TXMLHelper.WriteDocument: Document60 cannot be nil');
if stream = nil then
raise Exception.Create('TXMLHelper.WriteDocument: stream cannot be nil');
// Set properties on the XML writer - including BOM, XML declaration and encoding
writer := CoMXXMLWriter60.Create;
writer.byteOrderMark := True; //Determines whether to write the Byte Order Mark (BOM). The byteOrderMark property has no effect for BSTR or DOM output. (Default True)
writer.omitXMLDeclaration := False; //Forces the IMXWriter to skip the XML declaration. Useful for creating document fragments. (Default False)
if Encoding <> '' then
writer.encoding := Encoding; //Sets and gets encoding for the output. (Default "UTF-16")
writer.indent := True; //Sets whether to indent output. (Default False)
writer.standalone := True;
// Set the XML writer to the SAX content handler.
reader := CoSAXXMLReader60.Create;
reader.contentHandler := writer as IVBSAXContentHandler;
reader.dtdHandler := writer as IVBSAXDTDHandler;
reader.errorHandler := writer as IVBSAXErrorHandler;
reader.putProperty('http://xml.org/sax/properties/lexical-handler', writer);
reader.putProperty('http://xml.org/sax/properties/declaration-handler', writer);
writer.output := stream; //The resulting document will be written into the provided IStream
// Now pass the DOM through the SAX handler, and it will call the writer
reader.parse(Document60);
writer.flush;
end;
Note: Any code is released into the public domain. No attribution required.