let rec to_string_fmt (xml:Xml.xml):string= string_of_xml true xml and to_string (xml:Xml.xml):string= string_of_xml false xml and string_of_xml (fmt:bool) (xml:Xml.xml):string = match xml with |Xml.Element ((tag_name:string),(attr_list:(string*string) list),(xml_list:Xml.xml list)) -> ( let sep:string = match fmt with |false -> "" |true -> match contains_text xml_list with |true -> "" |false -> "\n" in match xml_list with |[] -> string_of_tag_open_close tag_name (string_of_attr_list attr_list) |_ -> String.concat sep [ string_of_tag_open tag_name (string_of_attr_list attr_list); String.concat sep (List.map (string_of_xml fmt) xml_list); string_of_tag_close tag_name; ] ) |Xml.PCData (s:string) -> s and contains_text (xml_list:Xml.xml list):bool = match xml_list with |[] -> false |hd::tl -> match hd with |Xml.Element ("a",_,_) |Xml.Element ("em",_,_) |Xml.PCData _ -> true |_ -> contains_text tl and string_of_tag_open (tag_name:string) (attrs:string):string = String.concat "" ["<";tag_name;attrs;">"] and string_of_tag_close (tag_name:string):string = String.concat "" ["</";tag_name;">"] and string_of_attr_list (attr_list:(string*string) list):string = match String.concat " " (List.map string_of_key_value_pair attr_list) with |""->"" |x -> (" " ^ x) and string_of_key_value_pair (key_value_pair:string*string):string = match key_value_pair with |(key,value) -> String.concat "" [key;"=";"\"";value;"\""] and string_of_tag_open_close (tag_name:string) (attrs:string):string = String.concat "" ["<";tag_name;attrs;"/>"]