{"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\u2019s 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\"><address<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"home\"<\/span><span class=\"hl kwa\">><\/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\"><address<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"work\"<\/span><span class=\"hl kwa\">><\/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\"><phone<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"work\"<\/span><span class=\"hl kwa\">><\/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\"><phone<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"home\"<\/span><span class=\"hl kwa\">><\/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\"><phone<\/span> <span class=\"hl kwb\">location<\/span>=<span class=\"hl str\">\"mobile\"<\/span><span class=\"hl kwa\">><\/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\u2019 names:<\/p>\n<pre class=\"hl\">\r\n  Fred Jones<\/pre>\n<p>In XQuery it\u2019s 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\u2019s an inferior solution to XQuery, because XPath doesn\u2019t provide a way for building XML documents. It\u2019s 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\u2019s the closest approach to XQuery. But the problem with XSLT is that it has its language constructs, like \u2018for\u2019 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\u2019s the most mature project for XQuery processing and it\u2019s 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\u2019s 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\u2019s 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\u2019s 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\">\u201chttp:\/\/my.org\/employees\u201d<\/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 \u2018this\u2019 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 \u2013 \u2018id\u2019 in this case.<br \/>\nHere\u2019s 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":["post-234","post","type-post","status-publish","format-standard","category-development-design","tag-java","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}]}}