[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Mikkel_Fahnøe_Jørgensen <mikkel@d...> |
| Subject: | Re: [Caml-list] xpath or alternatives |
2009/9/30 Richard Jones <rich@annexia.org>: > On Wed, Sep 30, 2009 at 01:00:15AM +0200, Mikkel Fahnøe Jørgensen wrote: >> In line with what Yaron suggests, you can use a combinator parser. > It's interesting you mention xmlm, because I couldn't write > the code using xmlm at all. If you can manage to convert an xml document into a json like tagged tree structure, then a simple solution like module Value = struct 56 type value_type = 57 Object of (string * value_type) list 58 | Array of value_type list 59 | String of string 60 | Int of int 61 | Float of float 62 | Bool of bool 63 | Null 64 end 65 .. 665 let get_object v = match v with Object x -> x 666 | _ -> fail "json object expected" .. 685 let pattern_path value names = 686 let rec again value = function 687 | "*" :: names -> List.iter (fun (n, v) -> try again v names 688 with Invalid_argument _ | Not_found -> ()) (get_object value) 689 | name :: names -> again (List.assoc name (get_object value)) names 690 | [] -> raise (Found value) 691 in try again value names; raise Not_found with Found value -> value 692 combined with a path split function 22 let split c s = 23 let n = String.length s in 24 let rec again i lst = 25 begin try let k = String.rindex_from s i c in 26 again (k - 1) ((if i = k then "" else (String.sub s (k + 1) (i - k))) :: lst) 27 with _ -> (String.sub s 0 (i + 1)) :: lst 28 end 29 in again (n - 1) [] will do almost exactly what you are asking for - notice the "*" searches broadly in all subtrees. You can add your own xpath like functions as you discover a need for them. I believe that the xmlm examples has a tree transformation operation that would easily be adapted to produce a json like tree, if modified a little. let out_tree o t = let frag = function | E (tag, childs) -> `El (tag, childs) | D d -> `Data d in Xmlm.output_doc_tree frag o t > My best effort, using xml-light, is around 40 lines: If you spend those 40 lines on a layer on top of a lightweight xml parser, you might get away with 3 lines the next time.