xml-light-2.2/0000700000175000017500000000000010217570536012600 5ustar gildorgildorxml-light-2.2/test.ml0000600000175000017500000000353110064525456014116 0ustar gildorgildor(* * Xml Light, an small Xml parser/printer with DTD support. * Copyright (C) 2003 Nicolas Cannasse (ncannasse@motion-twin.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) open Xml open Dtd let parse data = match data.[0] with | '#' -> Xml.parse_file (String.sub data 1 ((String.length data)-2)) | _ -> Xml.parse_string data ;; let buf = ref "" in print_endline "Please enter some XML data followed (press return twice to parse) :"; try while true do match read_line() with | "" when !buf <> "" -> let data = !buf in buf := ""; (try let x = parse data in print_endline "Parsing..."; print_endline (Xml.to_string_fmt x); with | Xml.Error msg as e -> Printf.printf "Xml error : %s\n" (Xml.error msg) | Dtd.Parse_error msg as e -> Printf.printf "Dtd parse error : %s\n" (Dtd.parse_error msg) | Dtd.Check_error msg as e -> Printf.printf "Dtd check error : %s\n" (Dtd.check_error msg) | Dtd.Prove_error msg as e -> Printf.printf "Dtd prove error : %s\n" (Dtd.prove_error msg)) | s -> buf := !buf ^ s ^ "\n" done with End_of_file -> print_endline "Exit."xml-light-2.2/Makefile0000600000175000017500000000544407742215734014256 0ustar gildorgildor# Makefile generated by OCamake # http://tech.motion-twin.com .SUFFIXES : .ml .mli .cmo .cmx .cmi .mll .mly INSTALLDIR=`ocamlc -where` CFLAGS= LFLAGS= -a LIBS= all: xml-light.cma test.exe doc opt: xml-light.cmxa test_opt.exe install: all opt cp xml-light.cmxa xml-light.a xml-light.cma xml.mli xmlParser.mli dtd.mli xml.cmi xmlParser.cmi dtd.cmi xml.cmx dtd.cmx xmlParser.cmx $(INSTALLDIR) doc: mkdir doc ocamldoc -sort -html -d doc xml.mli dtd.mli xmlParser.mli test.exe: xml-light.cma ocamlc xml-light.cma test.ml -o test.exe test_opt.exe: xml-light.cmxa ocamlopt xml-light.cmxa test.ml -o test_opt.exe xml-light.cma: xml_parser.cmo xml_lexer.cmo dtd.cmo xmlParser.cmo xml.cmo ocamlc -o xml-light.cma $(LFLAGS) $(LIBS) xml_parser.cmo xml_lexer.cmo dtd.cmo xmlParser.cmo xml.cmo xml-light.cmxa: xml_parser.cmx xml_lexer.cmx dtd.cmx xmlParser.cmx xml.cmx ocamlopt -o xml-light.cmxa $(LFLAGS) $(LIBS) xml_parser.cmx xml_lexer.cmx dtd.cmx xmlParser.cmx xml.cmx dtd.cmo: xml.cmi xml_lexer.cmi dtd.cmi dtd.cmx: xml.cmi xml_lexer.cmi dtd.cmi xml.cmo: dtd.cmi xmlParser.cmi xml_lexer.cmi xml.cmi xml.cmx: dtd.cmi xmlParser.cmi xml_lexer.cmi xml.cmi xmlParser.cmo: dtd.cmi xml.cmi xml_lexer.cmi xmlParser.cmi xmlParser.cmx: dtd.cmi xml.cmi xml_lexer.cmi xmlParser.cmi dtd.cmi: xml.cmi xml.cmi: xmlParser.cmi: dtd.cmi xml.cmi xml_lexer.cmi: dtd.cmi xml_parser.cmo: xml_parser.ml dtd.cmi xml_parser.mli xml_parser.cmi xml_parser.cmx: xml_parser.ml dtd.cmi xml_parser.mli xml_parser.cmi xml_lexer.cmo: xml_lexer.ml xml_lexer.cmi xml_lexer.cmx: xml_lexer.ml xml_lexer.cmi clean: rm -f xml-light.cma test.exe dtd.cmo dtd.cmi test.cmo test.cmi xml.cmo xml.cmi xmlParser.cmo xmlParser.cmi dtd.cmi xml.cmi xmlParser.cmi xml_lexer.cmi xml_lexer.cmo xml_lexer.ml xml_parser.mli xml_parser.cmi xml_parser.ml xml_parser.cmo rm -f xml_light.lib xml_light.a xml-light.cmxa test_opt.exe dtd.cmx dtd.obj dtd.o test.cmx test.obj test.o xml.cmx xml.obj xml.o xmlParser.cmx xmlParser.obj xmlParser.o xml_lexer.cmx xml_lexer.obj xml_lexer.o xml_parser.cmx xml_parser.obj xml_parser.o wclean: -@del xml-light.cma test.exe dtd.cmo dtd.cmi test.cmo test.cmi xml.cmo xml.cmi xmlParser.cmo xmlParser.cmi dtd.cmi xml.cmi xmlParser.cmi xml_lexer.cmi xml_lexer.cmo xml_lexer.ml xml_parser.mli xml_parser.cmi xml_parser.ml xml_parser.cmo 2>NUL -@del xml_light.lib xml_light.a xml-light.cmxa test_opt.exe dtd.cmx dtd.obj dtd.o test.cmx test.obj test.o xml.cmx xml.obj xml.o xmlParser.cmx xmlParser.obj xmlParser.o xml_lexer.cmx xml_lexer.obj xml_lexer.o xml_parser.cmx xml_parser.obj xml_parser.o 2>NUL # SUFFIXES .ml.cmo: ocamlc $(CFLAGS) -c $< .ml.cmx: ocamlopt $(CFLAGS) -c $< .mli.cmi: ocamlc $(CFLAGS) $< .mll.ml: ocamllex $< .mly.ml: ocamlyacc $< xml-light-2.2/README0000600000175000017500000000276010217570562013466 0ustar gildorgildorXml-Light Version 2.2 : ----------------------- Last version : http://tech.motion-twin.com Xml Light is a minimal Xml parser & printer for OCaml. It provide few functions to parse a basic Xml document into an OCaml data structure and to print back the data structures to an Xml document. Xml Light has also support for DTD (Document Type Definition). Install ------- make install by default, Xml Light is installed in the 'ocamlc -where' directory. you can change it by editing the Makefile. for Windows users, if you're using the MSVC version of ocaml and don't have cygwin tools installed, you can do : nmake all and then copy manually the files to the place you want. Usage ----- simple samples : -- parse / print an xml string --- let x = Xml.parse_string "TEXT" in Printf.printf "XML formated = \n%s" (Xml.to_string_fmt x); -- load an xml and a dtd , prove and print --- let x = Xml.parse_file "myfile.xml" in let dtd = Dtd.parse_file "myfile.dtd" in let x = Dtd.prove (Dtd.check dtd) "start" x in print_endline (Xml.to_string x) Documentation ------------- HTML documentation can be generated with ocamldoc : make doc you can also directly browse the MLI files to read it. Licence ------- Xml Light is LGPL Credits ------- (c)2003-2005 Nicolas Cannasse (ncannasse@motion-twin.com) (c)2003-2005 Motion-Twin Some parts of this code source has an additionnal copyright to Jacques Garrigue xml-light-2.2/xml_lexer.mll0000600000175000017500000003006510107060514015277 0ustar gildorgildor{(* * Xml Light, an small Xml parser/printer with DTD support. * Copyright (C) 2003 Nicolas Cannasse (ncannasse@motion-twin.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) open Lexing open Xml_parser open Dtd type error = | EUnterminatedComment | EUnterminatedString | EIdentExpected | ECloseExpected | ENodeExpected | EAttributeNameExpected | EAttributeValueExpected | EUnterminatedEntity type dtd_error = | EInvalidDTDDecl | EInvalidDTDTag | EDTDItemExpected | EInvalidDTDElement | EInvalidDTDAttribute exception Error of error exception DTDError of dtd_error type pos = int * int * int * int type dtd_decl = | DTDFile of string | DTDData of dtd type dtd_item_type = | TElement | TAttribute type token = | Tag of string * (string * string) list * bool | PCData of string | Endtag of string | DocType of (string * dtd_decl) | Eof let last_pos = ref 0 and current_line = ref 0 and current_line_start = ref 0 let tmp = Buffer.create 200 let idents = Hashtbl.create 0 let _ = begin Hashtbl.add idents "gt;" ">"; Hashtbl.add idents "lt;" "<"; Hashtbl.add idents "amp;" "&"; Hashtbl.add idents "apos;" "'"; Hashtbl.add idents "quot;" "\""; end let init lexbuf = current_line := 1; current_line_start := lexeme_start lexbuf; last_pos := !current_line_start let close lexbuf = Buffer.reset tmp let pos lexbuf = !current_line , !current_line_start , !last_pos , lexeme_start lexbuf let restore (cl,cls,lp,_) = current_line := cl; current_line_start := cls; last_pos := lp let newline lexbuf = incr current_line; last_pos := lexeme_end lexbuf; current_line_start := !last_pos let error lexbuf e = last_pos := lexeme_start lexbuf; raise (Error e) let dtd_error lexbuf e = last_pos := lexeme_start lexbuf; raise (DTDError e) } let newline = ['\n'] let break = ['\r'] let space = [' ' '\t'] let identchar = ['A'-'Z' 'a'-'z' '_' '0'-'9' ':' '-'] let entitychar = ['A'-'Z' 'a'-'z'] let pcchar = [^ '\r' '\n' '<' '>' '&'] rule token = parse | newline { newline lexbuf; token lexbuf } | (space | break) + { last_pos := lexeme_end lexbuf; token lexbuf } | "" { () } | eof { raise (Error EUnterminatedComment) } | _ { comment lexbuf } and header = parse | newline { newline lexbuf; header lexbuf } | "?>" { () } | eof { error lexbuf ECloseExpected } | _ { header lexbuf } and pcdata = parse | pcchar+ { Buffer.add_string tmp (lexeme lexbuf); pcdata lexbuf } | "&#" { Buffer.add_string tmp (lexeme lexbuf); pcdata lexbuf; } | '&' { Buffer.add_string tmp (entity lexbuf); pcdata lexbuf } | "" { Buffer.contents tmp } and entity = parse | entitychar+ ';' { let ident = lexeme lexbuf in try Hashtbl.find idents (String.lowercase ident) with Not_found -> "&" ^ ident } | _ | eof { raise (Error EUnterminatedEntity) } and ident_name = parse | identchar+ { lexeme lexbuf } | _ | eof { error lexbuf EIdentExpected } and close_tag = parse | '>' { () } | _ | eof { error lexbuf ECloseExpected } and attributes = parse | '>' { [], false } | "/>" { [], true } | "" (* do not read a char ! *) { let key = attribute lexbuf in let data = attribute_data lexbuf in ignore_spaces lexbuf; let others, closed = attributes lexbuf in (key, data) :: others, closed } and attribute = parse | identchar+ { lexeme lexbuf } | _ | eof { error lexbuf EAttributeNameExpected } and attribute_data = parse | space* '=' space* '"' { Buffer.reset tmp; last_pos := lexeme_end lexbuf; dq_string lexbuf } | space* '=' space* '\'' { Buffer.reset tmp; last_pos := lexeme_end lexbuf; q_string lexbuf } | _ | eof { error lexbuf EAttributeValueExpected } and dq_string = parse | '"' { Buffer.contents tmp } | '\\' [ '"' '\\' ] { Buffer.add_char tmp (lexeme_char lexbuf 1); dq_string lexbuf } | eof { raise (Error EUnterminatedString) } | _ { Buffer.add_char tmp (lexeme_char lexbuf 0); dq_string lexbuf } and q_string = parse | '\'' { Buffer.contents tmp } | '\\' [ '\'' '\\' ] { Buffer.add_char tmp (lexeme_char lexbuf 1); q_string lexbuf } | eof { raise (Error EUnterminatedString) } | _ { Buffer.add_char tmp (lexeme_char lexbuf 0); q_string lexbuf } and dtd_data = parse | "PUBLIC" { ignore_spaces lexbuf; (* skipping Public ID *) let _ = dtd_file lexbuf in let file = dtd_file lexbuf in dtd_end_decl lexbuf; DTDFile file } | "SYSTEM" { ignore_spaces lexbuf; let file = dtd_file lexbuf in dtd_end_decl lexbuf; DTDFile file } | '[' { ignore_spaces lexbuf; let data = dtd_intern lexbuf in dtd_end_decl lexbuf; DTDData data } | _ | eof { dtd_error lexbuf EInvalidDTDDecl } and dtd_file = parse | '"' { Buffer.reset tmp; let s = dq_string lexbuf in ignore_spaces lexbuf; s } | '\'' { Buffer.reset tmp; let s = q_string lexbuf in ignore_spaces lexbuf; s } | _ | eof { dtd_error lexbuf EInvalidDTDDecl } and dtd_intern = parse | ']' { ignore_spaces lexbuf; [] } | "" { let l = dtd_item lexbuf in l @ (dtd_intern lexbuf) } and dtd = parse | eof { [] } | newline { newline lexbuf; dtd lexbuf } | (space | break)+ { dtd lexbuf } | "" { let l = dtd_item lexbuf in l @ (dtd lexbuf) } and dtd_end_decl = parse | '>' { ignore_spaces lexbuf } | _ | eof { dtd_error lexbuf EInvalidDTDDecl } and dtd_item = parse | "