EDIT: Sorry, I overlooked, that you are looking for something to plug into OCaml. I let this comment here, nevertheless, since I put so much work into it ;-)
> I actually spent the last week looking for something like XPath done right
Have you tried XQuery? XQuery is a superset of XPath, currently (like XPath as well) at version 3.1. There is three major processors:
- eXist-db (much more than just an XQuery processor, but I believe, it can be used stand-alone)
- Saxon (only the PE/EE editions (commercial) implement current standards, SaxonHE, however, should fully support XQuery 1.0 (which is based on XPath2)
- BaseX (my favorite) Can be used as stand-alone, in REPL mode, behind a webserver (Jetty, Tomcat), or a very easy to use and simple but powerful IDE, and is extremly well done. Simple install.
declare function local:make-dynamic-element-node(
$name as xs:QName,
$attributes as map(*),
$contents as item()*)
as element(Q{http://example.org/ns/joecool}joecool)
{
element { $name } {
map:for-each($attributes, function($key, $value) {
attribute { $key } { $value }
})
, $contents
}
};
declare function local:make-literal-element-node(
$foo as xs:string?,
$bar as xs:string?
)
as element()
{
<joecool xmlns="http://example.org/ns/joecool" foo="{$foo}" moo="{$bar}">lorem ipsum</joecool>
};
let $at := map{
"foo": "bar"
, "moo": "test"
}
return (
local:make-dynamic-element-node(QName("http://example.org/ns/joecool", "joecool"), $at, "lorem ipsum")
, local:make-literal-element-node("value1","value2")
)
Result:
<joecool xmlns="http://example.org/ns/joecool" foo="bar" moo="test">lorem ipsum</joecool>
<joecool xmlns="http://example.org/ns/joecool" foo="value1" moo="value2">lorem ipsum</joecool>
Of course, this is just a small glimpse on this language, which can be typed or not, just as you prefer (I prototype untyped, then increase typing incrementally and release fully typed). It is a functional application programming language, that does great as backend, REST is supported and so much more. Just a glimpse on the build-in functions of BaseX (these are in addition to the XPath 3.1 function catalog, which has approx. 200 functions, now)
http://docs.basex.org/wiki/Module_Library