struct
    type t = {
      pmid : int ;
      title : string ;
      abstract : string ;
    }

    let parse_book_document bd =
      { pmid = ileaf_exn "PMID" bd ; 
        title = sleaf_exn "ArticleTitle" bd ;
        abstract = echild_exn "Abstract" bd |> sleaf_exn "AbstractText" }

    let parse_medline_citation mc = 
      let article = echild_exn "Article" mc in
      { pmid = ileaf_exn "PMID" mc ;
        title = sleaf_exn "ArticleTitle" article ;
        abstract = echild_exn "Abstract" article |> sleaf_exn "AbstractText" }

    let parse_pubmed_article_set_element x = match tag_of_tree x with
    | Some "PubmedArticle" -> 
        Some (parse_medline_citation (echild_exn "MedlineCitation" x))
    | Some "PubmedBookArticle" ->
        Some (parse_book_document (echild_exn "BookDocument" x))
    | Some t -> 
        failwith (sprintf "Unexpected %s tag while parsing PubmedArticleSet element" t)
    | None -> None

    let parse_pubmed_article_set = function
    | E ("PubmedArticleSet",_,children) ->
        List.filter_map ~f:parse_pubmed_article_set_element children
    | _ -> assert false
        
    let search = search_and_fetch `pubmed parse_pubmed_article_set
  end