let xml_of_channel ~date_fmt ch =
  let f v s = Element (s, [], [PCData v]) in
  let xml_ch =
    Element ("channel", [],
             (
              [ f ch.ch_title "title" ;
                f ch.ch_link "link" ;
                f ch.ch_desc "description" ;
              ] @
              (List.flatten
                 [ opt_element ch.ch_language "language" ;
                   opt_element ch.ch_copyright "copyright" ;
                   opt_element ch.ch_managing_editor "managingEditor" ;
                   opt_element ch.ch_webmaster "webMaster" ;
                   opt_element
                     (match ch.ch_pubdate with
                       None -> None
                     | Some d ->
                         err_date d ;
                         Some (Rss_date.format ~fmt: date_fmt d))
                     "pubDate" ;
                   opt_element
                     (match ch.ch_last_build_date with
                       None -> None
                     | Some d ->
                         err_date d ;
                         Some (Rss_date.format ~fmt: date_fmt d))
                     "lastBuildDate" ;
                   xmls_of_categories ch.ch_categories ;
                   opt_element ch.ch_generator "generator" ;
                   opt_element ch.ch_docs "docs" ;
                   opt_element
                     (apply_opt string_of_int ch.ch_ttl)
                     "ttl";
                   xmls_of_image_opt ch.ch_image ;
                   xmls_of_text_input_opt ch.ch_text_input ;
                   List.map (xml_of_item ~date_fmt) ch.ch_items ;
                 ]
              )
             )
            )
  in
  Element ("rss", ["version""2.0"], [xml_ch])