summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClombrong <cromblong@egregore.fun>2025-06-20 21:50:33 +0200
committerClombrong <cromblong@egregore.fun>2025-06-24 10:35:27 +0200
commitbcfd9027ea438870cc8a48f132907fe5f43d55ef (patch)
treef3b3f9946cfc64e5a60acc4e5bf857647cafffe8
parent2cc25f2635b590694dd81363a982873b5e184c30 (diff)
feat(xml): add function element_to_string
-rw-r--r--lib/xml.ml26
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/xml.ml b/lib/xml.ml
index 1b286bb..f568a0f 100644
--- a/lib/xml.ml
+++ b/lib/xml.ml
@@ -26,3 +26,29 @@ let tree s : element option =
and text ss = Either.Right (String.concat "" ss) in
let opt_el = tree ~text ~element s in
Option.bind opt_el (Either.fold ~left:Option.some ~right:(fun _ -> None))
+
+let element_to_string ?(indent = 2) (el : element) =
+ (** [element_to_string element] is a string representation of the underlying XML in
+ [element], for debugging purposes.
+
+ Note this isn't serialization: namely, XML namespaces are ignored. *)
+ let rec element_to_string {local_name; attributes; children; _} =
+ let attributes =
+ String.concat ""
+ (List.map (fun (n, a) -> " " ^ n ^ "=\"" ^ a ^ "\"") attributes)
+ in
+ let tab s =
+ String.split_on_char '\n' s |> String.concat ("\n" ^ String.make indent ' ')
+ in
+ let tag = "\n<" ^ local_name ^ attributes
+ in tag ^ match children with
+ | [] -> "/>"
+ | _ -> ">" ^ (children
+ |> List.map
+ (Either.fold
+ ~left:element_to_string
+ ~right:(fun x -> "\n" ^ x))
+ |> String.concat ""
+ |> tab)
+ ^ "\n</" ^ local_name ^ ">"
+ in element_to_string el |> String.trim