file handling for incident in self values()fh write('<incident report_id={report_id'date="{ date! }'aircraft_id={aircraft_id'aircraft_type={aircraft_type'pilot_percent_hours_on_type='"{ pilot_percent_hours_on_type}'pilot_total_hours="{ pilot_total_hours}'midair="{ midair: }">\ '{airport}\ '\ {narrative}\ \ '\nformat(incidentreport_id=xml sax saxutils quoteattrincident report_id)aircraft_id=xml sax saxutils quoteattrincident aircraft_id)aircraft_type=xml sax saxutils quoteattrincident aircraft_type)airport=xml sax saxutils escape(incident airport)narrative="\njoin(textwrap wrapxml sax saxutils escapeincident narrative strip()) )))fh write("\ "return true as we have often done in this we have omitted the except and finally blocks we write the file using the utf- encoding and must specify this to the built-in open(function strictly speakingwe don' have to specify the encoding in the declaration since utf- is the default encodingbut we prefer to be explicit we have chosen to quote all the attribute values using double quotes (")and so for convenience have used single quotes to quote the string we put the incidents in to avoid the need to escape the quotes the sax saxutils quoteattr(function is similar to the sax saxutils escape(function we use for xml text in that it properly escapes "&""characters in additionit escapes quotes (if necessary)and returns string that has quotes around it ready for use this is why we have not needed to put quotes around the report id and other string attribute values the newlines we have inserted and the text wrapping for the narrative are purely cosmetic they are designed to make the file easier for humans to read and editbut they could just as easily be omitted writing the data in html format is not much different from writing xml the convert-incidents py program includes the export_html(function as simple