How to insert DTD DOCTYPE content when using SAX to generate XML output in Python
Question: I am trying to generate a large XML file using python(actually jython)
xml.sax.saxutils.XMLGenerator. I would like to include DTD information but I
could not figure out how to pass the DTD string to SAX. Here is the sample SAX
writer class:

    
    
    from xml.sax.saxutils import XMLGenerator
    
    class xml_writer:
        def __init__(self, output, encoding):
            """
            an XML writer object that generate xml output to a file
            """
            xmlwriter = XMLGenerator(output, encoding)
            xmlwriter.startDocument()
            self._writer = xmlwriter
            self._output = output
            self._encoding = encoding
    
            self.attr_vals = {}
            self.attr_qnames = {}
            return
    
        def start_elem(self, name):
            name = unicode(name)
            attrs = AttributesNSImpl(self.attr_vals, self.attr_qnames)
            self._writer.startElementNS((None, name), name, attrs)
            self._writer._out.write('\n')
            self.attr_qnames = {}
            self.attr_vals = {}
    
        def end_elem(self, name):
            name = unicode(name)
            self._writer.endElementNS((None, name), name)
            self._writer._out.write('\n')
    
        def setAttribute(self, aname, value):
            aname = unicode(aname)
            value = unicode(value)
            self.attr_vals[(None, aname)] = value
            self.attr_qnames[(None, aname)] = aname
    
        def close(self):
            """
            Clean up 
            """
            self._writer.endDocument()
            return
    

Appreciate your help.


Answer: You could subclass `XMLGenerator` and add a `write()` method. Here is an
example:

    
    
    import sys
    from xml.sax.saxutils import XMLGenerator
    
    class MyXMLGenerator(XMLGenerator):
        def __init__(self, out=sys.stdout, encoding="UTF-8"):
            XMLGenerator.__init__(self, out, encoding)
            self.out = out
    
        def write (self,s):
            self.out.write(s)
    
    def writexml(out):
        xmlwriter = MyXMLGenerator(out)
        xmlwriter.startDocument()
        xmlwriter.write("<!DOCTYPE test SYSTEM 'test.dtd'>\n")
        xmlwriter.startElement('test', {"a": "1"})
        xmlwriter.characters('abc123')
        xmlwriter.endElement('test')
        xmlwriter.endDocument()
    
    if __name__ == '__main__':
        writexml(out=open("out.xml", "w"))
    

Resulting output in **out.xml** :

    
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE test SYSTEM 'test.dtd'>
    <test a="1">abc123</test>
    

