If I understand your question, you can achieve what you want in two different ways.
You use a mutable data structure on your tag type, like the following example:
type tag = string ref;;
type xml = Element of tag * xml list | CharData of string;;
let xml_test = Element (ref "person",
[CharData "text0";
Element (ref "phoneNumber", [CharData "text2"]);
CharData "text1";
Element (ref "phoneNumber", [CharData "text3"])]);;
let modify_tag tag new_value=
tag := new_value;;
let rec modify_and_print_xml xml =
match xml with
Element (tag, xlist) -> modify_tag tag (!tag^"_modified");
print_string (!tag); print_newline ();
(*here you do the recursive call*)
List.iter (fun element -> modify_and_print_xml element) xlist
|CharData str -> print_string str; print_newline ();;
modify_and_print_xml xml_test;;
Otherwise and since you are new to functional programming, the best way to think about it, is not to modify the tag value in place, but construct a new xml value that has the modified tag (this is what you should do to code purely functional and eliminate side effects).
Here is an example, say you want modify every tag named "phoneNumber" to "phone":
let rec get_modified_xml xml =
match xml with
Element (tag, xlist) -> if (!tag = "phoneNumber") then
Element(ref "phone", List.map (fun element -> get_modified_xml element) xlist)
else
Element (tag, List.map (fun element -> get_modified_xml element) xlist)
| _ -> xml;;
get_modified_xml xml_test;;
output :
- : xml =
Element ({contents = "person"},
[CharData "text0"; Element ({contents = "phone"}, [CharData "text2"]);
CharData "text1"; Element ({contents = "phone"}, [CharData "text3"])])