+ Some (getter key)
+ with Key_not_found _ -> None
+let set_opt setter ~key ~value =
+ match value with
+ | None -> unset key
+ | Some value -> setter ~key ~value
+
+let add_validator ~key ~validator ~descr =
+ let id = get_next_validator_id () in
+ Hashtbl.add validators key (validator, descr);
+ id
+
+open Pxp_dtd
+open Pxp_document
+open Pxp_types
+open Pxp_yacc
+
+let save_to =
+ let dtd = new dtd default_config.warner `Enc_utf8 in
+ let dot_RE = Str.regexp "\\." in
+ let create_key_node key value = (* create a <key name="foo">value</key> *)
+ let element =
+ create_element_node ~valcheck:false default_spec dtd "key" ["name", key]
+ in
+ let data = create_data_node default_spec dtd value in
+ element#append_node data;
+ element
+ in
+ let is_section name =
+ fun node ->
+ match node#node_type with
+ | T_element "section" ->
+ (try node#attribute "name" = Value name with Not_found -> false)
+ | _ -> false
+ in
+ let add_key_node root sections key value =
+ let rec aux node = function
+ | [] ->
+ let key_node = create_key_node key value in
+ node#append_node key_node
+ | section :: tl ->
+ let next_node =
+ try
+ find ~deeply:false (is_section section) node
+ with Not_found ->
+ let section_node =
+ create_element_node ~valcheck:false default_spec dtd
+ "section" ["name", section]
+ in
+ node#append_node section_node;
+ section_node
+ in
+ aux next_node tl
+ in
+ aux root sections
+ in
+ fun fname ->
+ let xml_root =
+ create_element_node ~valcheck:false default_spec dtd "helm_registry" []
+ in