{"id":234,"date":"2010-01-17T00:11:00","date_gmt":"2010-01-16T22:11:00","guid":{"rendered":""},"modified":"2023-03-20T12:28:38","modified_gmt":"2023-03-20T11:28:38","slug":"embedding-xquery-in-java","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2010\/01\/17\/embedding-xquery-in-java\/","title":{"rendered":"Embedding XQuery in Java"},"content":{"rendered":"<p>XQuery is a very powerful language. It can be very useful when you want to do some XML processing in Java.<br \/>\nLet&#8217;s say you want to create an XML document based on some other XML data. Given something like this:<\/p>\n<pre class=\"hl\">\r\n  \r\n    Fred Jones\r\n    <span class=\"hl kwa\">&lt;address<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"home\"<\/span><span class=\"hl kwa\">&gt;<\/span>\r\n      <span class=\"hl num\">900<\/span> Aurora Ave.\r\n      Seattle\r\n      WA\r\n      <span class=\"hl num\">98115<\/span>\r\n    \r\n    <span class=\"hl kwa\">&lt;address<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"work\"<\/span><span class=\"hl kwa\">&gt;<\/span>\r\n      <span class=\"hl num\">2011 152<\/span>nd Avenue NE\r\n      Redmond\r\n      WA\r\n      <span class=\"hl num\">98052<\/span>\r\n    \r\n    <span class=\"hl kwa\">&lt;phone<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"work\"<\/span><span class=\"hl kwa\">&gt;<\/span>(<span class=\"hl num\">425<\/span>)<span class=\"hl num\">555<\/span>-<span class=\"hl num\">5665<\/span>\r\n    <span class=\"hl kwa\">&lt;phone<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"home\"<\/span><span class=\"hl kwa\">&gt;<\/span>(<span class=\"hl num\">206<\/span>)<span class=\"hl num\">555<\/span>-<span class=\"hl num\">5555<\/span>\r\n    <span class=\"hl kwa\">&lt;phone<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"mobile\"<\/span><span class=\"hl kwa\">&gt;<\/span>(<span class=\"hl num\">206<\/span>)<span class=\"hl num\">555<\/span>-<span class=\"hl num\">4321<\/span>\r\n  \r\n<\/pre>\n<p>You want to produce employees&#8217; names:<\/p>\n<pre class=\"hl\">\r\n  Fred Jones<\/pre>\n<p>In XQuery it&#8217;s just as easy as:<\/p>\n<pre class=\"hl\">\r\n  {for $name in employees\/employee\/name\/text() return {$name}}<\/pre>\n<p>The most interesting advantage for XQuery over various other methods for generating XML is that XQuery operates natively on XML.<br \/>\nThere are tools like JaxB, XmlBeans, which enable strongly typed XML building directly from Java code. But using such approach often requires a lot of Java code to be written, which is not really necessary.<br \/>\nThere is also a possibility to use XPath. However it&#8217;s an inferior solution to XQuery, because XPath doesn&#8217;t provide a way for building XML documents. It&#8217;s designed only for nodes selection. On the other hand, XQuery extends XPath, so it supports every construct that XPath does.<br \/>\nAnother way to do such processing in Java is to use XSLT. It&#8217;s the closest approach to XQuery. But the problem with XSLT is that it has its language constructs, like &#8216;for&#8217; expressed as XML elements. This makes writing XSLT code much more difficult that XQuery.<br \/>\nXQuery can be seen as a native template language for XML processing.<br \/>\nSo the question is: how to evaluate XQuery expressions the best way from Java?<br \/>\nThere are some Open Source implementations of XQuery for Java. One of them is inside XmlBeans. However in my opinion the best way is to use Saxon. It&#8217;s the most mature project for XQuery processing and it&#8217;s targetted directly for doing that.<br \/>\nHowever Saxon might be a bit difficult to use directly. At least digging a few interesting features from it took me some time.<br \/>\nSo I decided to write a simple class for interfacing Saxon and to provide a few interesting examples of how to use it. That&#8217;s how xquery4j was born. You can download it from github <a href=\"http:\/\/github.com\/rafalrusin\/xquery4j\">http:\/\/github.com\/rafalrusin\/xquery4j<\/a>.<br \/>\nIn xquery4j, you can execute XQuery expressions from Java in a simple way:<\/p>\n<pre class=\"hl\">XQueryEvaluator evaluator <span class=\"hl sym\">=<\/span> <span class=\"hl kwa\">new<\/span> <span class=\"hl kwd\">XQueryEvaluator<\/span><span class=\"hl sym\">();<\/span>\r\n<span class=\"hl kwc\">Long<\/span> result <span class=\"hl sym\">= (<\/span><span class=\"hl kwc\">Long<\/span><span class=\"hl sym\">)<\/span> evaluator<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">evaluateExpression<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"5+5\"<\/span><span class=\"hl sym\">,<\/span> null<span class=\"hl sym\">).<\/span><span class=\"hl kwd\">get<\/span><span class=\"hl sym\">(<\/span><span class=\"hl num\">0<\/span><span class=\"hl sym\">);<\/span>\r\nAssert<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">assertEquals<\/span><span class=\"hl sym\">(<\/span><span class=\"hl kwa\">new<\/span> <span class=\"hl kwc\">Long<\/span><span class=\"hl sym\">(<\/span><span class=\"hl num\">10<\/span><span class=\"hl sym\">),<\/span> result<span class=\"hl sym\">);<\/span><\/pre>\n<p>It&#8217;s possible to bind variables from Java objects, the easy way:<\/p>\n<pre class=\"hl\">evaluator<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">bindVariable<\/span><span class=\"hl sym\">(<\/span><span class=\"hl kwc\">QName<\/span><span class=\"hl sym\">.<\/span><span class=\"hl kwd\">valueOf<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"myVar\"<\/span><span class=\"hl sym\">),<\/span> <span class=\"hl num\">123<\/span><span class=\"hl sym\">);<\/span><\/pre>\n<p>Sometimes it&#8217;s also useful to declare Java methods and bind them for XQuery expressions. This is also very simple to do with xquery4j:<\/p>\n<pre class=\"hl\"><span class=\"hl kwa\">public static class<\/span> MyFunctions <span class=\"hl sym\">{<\/span>\r\n        <span class=\"hl kwa\">public static<\/span> <span class=\"hl kwc\">String<\/span> <span class=\"hl kwd\">myHello<\/span><span class=\"hl sym\">(<\/span><span class=\"hl kwc\">String<\/span> arg<span class=\"hl sym\">) {<\/span>\r\n            TestEvaluator te <span class=\"hl sym\">= (<\/span>TestEvaluator<span class=\"hl sym\">)<\/span> XQueryEvaluator<span class=\"hl sym\">.<\/span>contextObjectTL<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">get<\/span><span class=\"hl sym\">();<\/span>\r\n            te<span class=\"hl sym\">.<\/span>id<span class=\"hl sym\">++;<\/span>\r\n            <span class=\"hl kwa\">return<\/span> <span class=\"hl str\">\"hello(\"<\/span> <span class=\"hl sym\">+<\/span> arg <span class=\"hl sym\">+<\/span> te<span class=\"hl sym\">.<\/span>id <span class=\"hl sym\">+<\/span> <span class=\"hl str\">\")\"<\/span><span class=\"hl sym\">;<\/span>\r\n        <span class=\"hl sym\">}<\/span>\r\n    <span class=\"hl sym\">}<\/span><\/pre>\n<p>XQueryEvaluator evaluator <span class=\"hl sym\">=<\/span> <span class=\"hl kwa\">new<\/span> <span class=\"hl kwd\">XQueryEvaluator<\/span><span class=\"hl sym\">();<\/span><br \/>\nevaluator<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">setContextObject<\/span><span class=\"hl sym\">(<\/span><span class=\"hl kwa\">this<\/span><span class=\"hl sym\">);<\/span><br \/>\nevaluator<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">declareJavaClass<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">&#8220;http:\/\/my.org\/employees&#8221;<\/span><span class=\"hl sym\">,<\/span> MyFunctions<span class=\"hl sym\">.<\/span><span class=\"hl kwa\">class<\/span><span class=\"hl sym\">);<\/span><br \/>\n<span class=\"hl sym\">}<\/span><br \/>\nThis code sets a context object to &#8216;this&#8217; and binds all static methods from MyFunctions class to XQuery expressions. So during myHello execution from XQuery, you can easily operate on Java variables from bound context &#8211; &#8216;id&#8217; in this case.<br \/>\nHere&#8217;s a way of invoking such bound myHello method from XQuery:<\/p>\n<pre class=\"hl\">declare namespace my = 'http:\/\/my.org\/employees'; my:myHello(<span class=\"hl str\">\"hello\"<\/span>)<\/pre>\n<p>xquery4j code contains unit tests, which include examples above.<br \/>\nYou can run them by:<\/p>\n<pre class=\"hl\">mvn package<\/pre>\n<p>Feel free to give some feedback on using it.<\/p>\n<div class=\"blogger-post-footer\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/tracker\/6983141563768732668-7594550166246467171?l=rrusin.blogspot.com\" alt=\"\" width=\"1\" height=\"1\" \/><\/div>\n","protected":false},"excerpt":{"rendered":"XQuery is a very powerful language. It can be very useful when you want to do some XML&hellip;\n","protected":false},"author":35,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[68,107],"class_list":{"0":"post-234","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-development-design","7":"tag-java","8":"tag-xml"},"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=234"}],"version-history":[{"count":32,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/234\/revisions"}],"predecessor-version":[{"id":15320,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/234\/revisions\/15320"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}