Module Xmlr


module Xmlr: sig .. end
Interface to libxml's XMLReader.


XMLReader is a simple API that lets you imperatively move a cursor through your XML document. It is simpler than SAX because there are no callbacks and it is simpler than DOM because it doesn't need the entire document in memory.

The Xmlr API provides a reader type, which represents the cursor within the document. A reader can only be advanced, and most of the functions return information about the node the reader is currently at.

Types


type t 
The type of the reader.

type nodetype =
| NodeTypeNone
| StartElement
| Attribute
| Text
| CData
| EntityRef
| EntityDecl
| PI
| Comment
| Document
| Doctype
| Fragment
| Notation
| Whitespace
| SigWhitespace
| EndElement
| EndEntity
| XMLDecl
The type of the current node of the reader.
val string_of_nodetype : nodetype -> string
Return a string version of a node type. Useful for debugging.

type parser_option =
| Recover
| NoEnt
| DTDLoad
| DTDAttr
| DTDValid
| NoError
| NoWarning
| Pedantic
| NoBlanks
| SAX1
| XInclude
| NoNet
| NoDict
| NSClean
| NoCDATA
The type of options for the XML parser.

Reading functions



Creating a reader


val from_filename : ?encoding:string -> ?opts:parser_option list -> string -> t
Create a new reader from a filename.
val from_string : ?baseurl:string ->
?encoding:string -> ?opts:parser_option list -> string -> t
Create a new reader from a string.

Moving the reader cursor


val read : t -> bool
Read the next node. Returns true if there was a node, false if there wasn't, and raises an exception on error.
val next : t -> bool
Skip to the node following the current one in document order while avoiding the subtree if any. Returns false if there isn't a node following the current one, and raises an exception on error.

Queries about the current node


val node_type : t -> nodetype
Returns the nodetype of the current node.
val prefix : t -> string
Returns the prefix defining the namespace associated with the current node.
val local_name : t -> string
Returns the local name of the current node.
val name : t -> string
Returns the current name of the node, equal to prefix:localname.
val namespace_uri : t -> string
Returns the URI defining the namespace associated with the current node.
val has_value : t -> bool
Returns true if the current node has a text value.
val value : t -> string
Returns the text value of the node.
val base_uri : t -> string
Returns the base URI of the current node.
val is_empty_element : t -> bool
Returns true if the current node is an empty element.
val depth : t -> int
Returns the depth of current node in the tree.

Node Attributes


val has_attributes : t -> bool
Returns true if the current element has attributes.
val attribute_count : t -> int
Returns the number of attributes of the current element.
val get_attribute : t -> string -> string
get_attribute reader attr gets the value of the attribute with the qualified name attr. Raises Not_found if the attribute doesn't exist.
val get_attribute_no : t -> int -> string
get_attribute_no reader n returns the value of the nth attribute. Raises Not_found if the attribute doesn't exist.
val get_attribute_ns : t -> string -> string -> string
get_attribute reader ns attr gets the value of the attribute with the namespace ns and name attr. Raises Not_found if the attribute doesn't exist.

Helper functions



These functions are experimental and are likely to change in the future.
val skip_to_close : t -> string -> unit
skip_to_close r tag reads r forward up the next closing tag with name tag. Raises Not_found if there is no closing tag.
val fold_subnodes : t -> string -> 'a -> (string -> 'a -> 'a) -> 'a
fold_subnodes reader tag initial f iterates reader through the subnodes of the current tag, passing each node to f along with the current state, which f transforms. After fold_subnodes runs, reader is positioned at the closing tag.

Example:

type person = { person_firstname : string;
                person_lastname : string }
let empty_person = { person_firstname=""; person_lastname="" }
let sample_xml = "<person><firstname>John</firstname><lastname>Doe</lastname></person>"
let johndoe =
  let r = Xmlr.from_string sample_xml in
  if not (Xmlr.read r) then failwith "Cannot find start element";
  if (Xmlr.node_type r <> Xmlr.StartElement ||
      Xmlr.name r <> "person"then failwith "Bad start element";
  Xmlr.fold_subnodes r "person" empty_person (fun tag person ->
    match tag with
      "firstname" -> { person with person_firstname = Xmlr.value r }
    | "lastname" -> { person with person_lastname = Xmlr.value r }
    | _ -> person)

val iter_subnodes : t -> string -> (string -> unit) -> unit
iter_subnodes r tag f calls f on each subnode of the current node, ending at tag.