How to make XMLDOMDocument include the XML Declaration?

后端 未结 5 1170
小鲜肉
小鲜肉 2021-01-12 06:29

When an XMLDOMDocument saves itself, how can i get it to include the XML Declaration, e.g.:

5条回答
  •  南笙
    南笙 (楼主)
    2021-01-12 07:29

    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.

提交回复
热议问题