Added XQuery Tool and refactored tools-service (#220)
Co-authored-by: Adam Bem <adam.bem@zoho.eu> Reviewed-on: #220 Reviewed-by: Mikolaj Widla <widlam@noreply.example.com>
This commit is contained in:
		| @@ -54,7 +54,7 @@ def process_xml(request: request, type: str) -> str: | |||||||
|         code = 400 |         code = 400 | ||||||
|     finally: |     finally: | ||||||
|         exec_time = (time.time_ns() - start) / 10**6 |         exec_time = (time.time_ns() - start) / 10**6 | ||||||
|         response_json['time'] = f"{exec_time:.03f}" |         response_json['duration'] = f"{exec_time:.03f}" | ||||||
|         response_json['processor'] = "libxml2 over lxml" |         response_json['processor'] = "libxml2 over lxml" | ||||||
|         return json.dumps(response_json), code |         return json.dumps(response_json), code | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,11 +2,7 @@ package com.r11.tools; | |||||||
|  |  | ||||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||||
| import com.google.gson.GsonBuilder; | import com.google.gson.GsonBuilder; | ||||||
| import com.r11.tools.controller.JsonController; | import com.r11.tools.controller.*; | ||||||
| import com.r11.tools.controller.ProcessorInfoController; |  | ||||||
| import com.r11.tools.controller.XPathController; |  | ||||||
| import com.r11.tools.controller.XsdController; |  | ||||||
| import com.r11.tools.controller.XsltController; |  | ||||||
| import com.r11.tools.controller.internal.RestControllerRegistry; | import com.r11.tools.controller.internal.RestControllerRegistry; | ||||||
| import com.r11.tools.xml.Saxon; | import com.r11.tools.xml.Saxon; | ||||||
| import com.r11.tools.xml.Xalan; | import com.r11.tools.xml.Xalan; | ||||||
| @@ -48,6 +44,7 @@ public class SparkApplication { | |||||||
|         registry.registerController(new XPathController(gson, logger, saxon, xalan)); |         registry.registerController(new XPathController(gson, logger, saxon, xalan)); | ||||||
|         registry.registerController(new XsltController(gson, logger, saxon, xalan)); |         registry.registerController(new XsltController(gson, logger, saxon, xalan)); | ||||||
|         registry.registerController(new JsonController(gson, jsongson, logger)); |         registry.registerController(new JsonController(gson, jsongson, logger)); | ||||||
|  |         registry.registerController(new XQueryController(gson, logger, saxon)); | ||||||
|  |  | ||||||
|         registry.register(); |         registry.register(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,8 +1,10 @@ | |||||||
| package com.r11.tools.controller; | package com.r11.tools.controller; | ||||||
|  |  | ||||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||||
| import com.google.gson.JsonObject; |  | ||||||
| import com.r11.tools.controller.internal.*; | import com.r11.tools.controller.internal.*; | ||||||
|  | import com.r11.tools.model.XMLRequestBody; | ||||||
|  | import com.r11.tools.model.XMLResponseBody; | ||||||
|  | import com.r11.tools.model.XPathQueryResult; | ||||||
| import com.r11.tools.xml.XmlEngine; | import com.r11.tools.xml.XmlEngine; | ||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
| import spark.Request; | import spark.Request; | ||||||
| @@ -24,109 +26,69 @@ public class XPathController implements RestController { | |||||||
|         this.xalan = xalan; |         this.xalan = xalan; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @ScopedControllerManifest(method = HandlerType.POST, path = "/xpath") |     private XMLResponseBody errorResponse(String message, String processor) { | ||||||
|     public void transform(Request request, Response response) { |         return new XMLResponseBody(message, "ERR", processor, -1); | ||||||
|         String body = request.body(); |     } | ||||||
|  |  | ||||||
|         JsonObject requestJson; |  | ||||||
|         try { |  | ||||||
|             requestJson = this.gson.fromJson(body, JsonObject.class); |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             JsonObject responseJson = new JsonObject(); |  | ||||||
|             responseJson.addProperty("result", e.getMessage()); |  | ||||||
|             responseJson.addProperty("processor", "N/A"); |  | ||||||
|             responseJson.addProperty("status", "ERR"); |  | ||||||
|             responseJson.addProperty("time", "N/A"); |  | ||||||
|  |  | ||||||
|  |     private void nonValidEngineSelectedResponse(Response response) { | ||||||
|  |         XMLResponseBody responseBody = | ||||||
|  |                 errorResponse("Valid engines are: saxon, xalan", "N/A"); | ||||||
|  |         response.body(this.gson.toJson(responseBody)); | ||||||
|         response.status(400); |         response.status(400); | ||||||
|             response.body(this.gson.toJson(responseJson)); |     } | ||||||
|  |  | ||||||
|  |     @ScopedControllerManifest(method = HandlerType.POST, path = "/xpath") | ||||||
|  |     public void acceptRequest(Request request, Response response) { | ||||||
|  |         XMLRequestBody requestBody; | ||||||
|  |         try { | ||||||
|  |             requestBody = this.gson.fromJson(request.body(), XMLRequestBody.class); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             XMLResponseBody responseBody = errorResponse(e.getMessage(), "N/A"); | ||||||
|  |             response.status(400); | ||||||
|  |             response.body(this.gson.toJson(responseBody)); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         String data = requestJson.get("data").getAsString(); |         if (requestBody.getProcessor() == null) { | ||||||
|         String query = requestJson.get("process").getAsString(); |             nonValidEngineSelectedResponse(response); | ||||||
|         String processor = requestJson.get("processor").getAsString(); |  | ||||||
|         String version = requestJson.get("version").getAsString(); |  | ||||||
|  |  | ||||||
|         if (processor == null) { |  | ||||||
|             response.body("saxon, xalan"); |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         JsonObject responseJson = new JsonObject(); |         switch (requestBody.getProcessor()) { | ||||||
|         switch (processor) { |  | ||||||
|             case "saxon": |             case "saxon": | ||||||
|                 processWithSaxon(response, data, query, version, responseJson); |                 process(response, requestBody, saxon); | ||||||
|                 break; |                 break; | ||||||
|             case "xalan": |             case "xalan": | ||||||
|                 processWithXalan(response, data, query, responseJson); |                 process(response, requestBody, xalan); | ||||||
|                 break; |                 break; | ||||||
|             default: |             default: | ||||||
|                 response.body("saxon, xalan"); |                 nonValidEngineSelectedResponse(response); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void processWithXalan(Response response, String data, String query, JsonObject responseJson) { |     private void process(Response response, XMLRequestBody requestBody, XmlEngine engine) { | ||||||
|         long timeStart; |         long timeStart = System.currentTimeMillis(); | ||||||
|         long duration; |         XMLResponseBody responseBody = null; | ||||||
|         response.header("processor", xalan.getVersion()); |  | ||||||
|         timeStart = System.currentTimeMillis(); |  | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             XPathQueryResult xPathQueryResult = xalan.processXPath(data, query, ""); |             XPathQueryResult xPathQueryResult = | ||||||
|  |                     engine.processXPath(requestBody.getData(), requestBody.getProcess(), requestBody.getVersion()); | ||||||
|  |  | ||||||
|             response.status(200); |             response.status(200); | ||||||
|  |             long duration = System.currentTimeMillis() - timeStart; | ||||||
|  |             responseBody = new XMLResponseBody(xPathQueryResult.getData().trim(), | ||||||
|  |                     "OK", engine.getVersion(),duration); | ||||||
|              |              | ||||||
|             responseJson.addProperty("result", xPathQueryResult.getData().trim()); |             responseBody.setType(xPathQueryResult.getType()); | ||||||
|             responseJson.addProperty("status", "OK"); |             this.logger.info("Request (XPath, " + engine.getVersion() + ") processed in " + duration + " ms."); | ||||||
|             responseJson.addProperty("type", xPathQueryResult.getType()); |  | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             this.logger.error("Error on processing XPath using Xalan. " + ex); |             responseBody = errorResponse(ex.getMessage(), engine.getVersion()); | ||||||
|  |  | ||||||
|             response.status(400); |             response.status(400); | ||||||
|  |  | ||||||
|             responseJson.addProperty("result", ex.getMessage()); |             this.logger.error("Error on processing XPath using " + engine.getVersion() + ". " + ex); | ||||||
|             responseJson.addProperty("status", "ERR"); |         } finally { | ||||||
|  |             response.body(this.gson.toJson(responseBody)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         duration = System.currentTimeMillis() - timeStart; |  | ||||||
|         this.logger.info("Request (XPath, Xalan) processed in " + duration + " ms."); |  | ||||||
|  |  | ||||||
|         responseJson.addProperty("processor", xalan.getVersion()); |  | ||||||
|         responseJson.addProperty("time", duration); |  | ||||||
|  |  | ||||||
|         response.body(this.gson.toJson(responseJson)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void processWithSaxon(Response response, String data, String query, String version, JsonObject responseJson) { |  | ||||||
|         long timeStart; |  | ||||||
|         String tmp; |  | ||||||
|         long duration; |  | ||||||
|         response.header("processor", "Saxon " + saxon.getVersion() + " " + version + " over s9api"); |  | ||||||
|         timeStart = System.currentTimeMillis(); |  | ||||||
|  |  | ||||||
|         try { |  | ||||||
|             tmp = saxon.processXPath(data, query, version).getData().trim(); |  | ||||||
|  |  | ||||||
|             response.status(200); |  | ||||||
|  |  | ||||||
|             responseJson.addProperty("result", tmp); |  | ||||||
|             responseJson.addProperty("status", "OK"); |  | ||||||
|         } catch (Exception ex) { |  | ||||||
|             this.logger.error("Error on processing XPath using Saxon. " + ex); |  | ||||||
|  |  | ||||||
|             response.status(400); |  | ||||||
|  |  | ||||||
|             responseJson.addProperty("result", ex.getMessage()); |  | ||||||
|             responseJson.addProperty("status", "ERR"); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         duration = System.currentTimeMillis() - timeStart; |  | ||||||
|         this.logger.info("Request (XPath, Saxon) processed in " + duration + " ms."); |  | ||||||
|  |  | ||||||
|         responseJson.addProperty("processor", "Saxon " + saxon.getVersion() + " " + version + " over s9api"); |  | ||||||
|         responseJson.addProperty("time", duration); |  | ||||||
|  |  | ||||||
|         response.body(this.gson.toJson(responseJson)); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,87 @@ | |||||||
|  | package com.r11.tools.controller; | ||||||
|  |  | ||||||
|  | import com.google.gson.Gson; | ||||||
|  | import com.r11.tools.controller.internal.*; | ||||||
|  | import com.r11.tools.model.XMLRequestBody; | ||||||
|  | import com.r11.tools.model.XMLResponseBody; | ||||||
|  | import com.r11.tools.xml.XmlEngine; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import spark.Request; | ||||||
|  | import spark.Response; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Controller used to handle XQuery tool. Currently, it supports Saxon engine | ||||||
|  |  * @author Adam Bem | ||||||
|  |  */ | ||||||
|  | @GlobalControllerManifest | ||||||
|  | public class XQueryController implements RestController { | ||||||
|  |  | ||||||
|  |     private final Gson gson; | ||||||
|  |     private final Logger logger; | ||||||
|  |     private final XmlEngine saxon; | ||||||
|  |  | ||||||
|  |     public XQueryController(Gson gson, Logger logger, XmlEngine saxon) { | ||||||
|  |         this.gson = gson; | ||||||
|  |         this.logger = logger; | ||||||
|  |         this.saxon = saxon; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private XMLResponseBody prepareErrorResponse(String message, String processor) { | ||||||
|  |         return new XMLResponseBody(message, "ERR", processor, -1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void nonValidEngineSelectedResponse(Response response) { | ||||||
|  |         XMLResponseBody responseBody = | ||||||
|  |                 prepareErrorResponse("Valid engines are: saxon", "N/A"); | ||||||
|  |         response.body(this.gson.toJson(responseBody)); | ||||||
|  |         response.status(400); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ScopedControllerManifest(method = HandlerType.POST, path = "/xquery") | ||||||
|  |     public void acceptRequest(Request request, Response response) { | ||||||
|  |         XMLRequestBody requestBody; | ||||||
|  |         try { | ||||||
|  |             requestBody = this.gson.fromJson(request.body(), XMLRequestBody.class); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             XMLResponseBody responseBody = prepareErrorResponse(e.getMessage(), "N/A"); | ||||||
|  |  | ||||||
|  |             response.status(400); | ||||||
|  |             response.body(this.gson.toJson(responseBody)); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if (requestBody.getProcessor() == null) { | ||||||
|  |             nonValidEngineSelectedResponse(response); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         if (requestBody.getProcessor().equalsIgnoreCase("saxon")) | ||||||
|  |             process(response, requestBody, saxon); | ||||||
|  |         else | ||||||
|  |             nonValidEngineSelectedResponse(response); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void process(Response response, XMLRequestBody requestBody, XmlEngine engine) { | ||||||
|  |         XMLResponseBody responseBody = null; | ||||||
|  |         long timeStart = System.currentTimeMillis(); | ||||||
|  |         try { | ||||||
|  |             String result = engine.executeXQuery(requestBody.getData(), requestBody.getProcess(), requestBody.getVersion()); | ||||||
|  |  | ||||||
|  |             response.status(200); | ||||||
|  |  | ||||||
|  |             long duration = System.currentTimeMillis() - timeStart; | ||||||
|  |             responseBody = new XMLResponseBody(result, "OK", engine.getVersion(), duration); | ||||||
|  |  | ||||||
|  |             this.logger.info("Request (XQuery, " + engine.getVersion() + ") processed in " + duration + " ms."); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             response.status(400); | ||||||
|  |             responseBody = prepareErrorResponse(ex.getMessage(), engine.getVersion()); | ||||||
|  |  | ||||||
|  |             this.logger.error("Error on processing XQuery using " + engine.getVersion() + ". " + ex); | ||||||
|  |         } | ||||||
|  |         finally { | ||||||
|  |             response.body(this.gson.toJson(responseBody)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,12 +1,9 @@ | |||||||
| package com.r11.tools.controller; | package com.r11.tools.controller; | ||||||
|  |  | ||||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||||
| import com.google.gson.JsonObject; | import com.r11.tools.controller.internal.*; | ||||||
| import com.r11.tools.controller.internal.GlobalControllerManifest; | import com.r11.tools.model.XMLRequestBody; | ||||||
| import com.r11.tools.controller.internal.HandlerType; | import com.r11.tools.model.XMLResponseBody; | ||||||
| import com.r11.tools.controller.internal.RestController; |  | ||||||
| import com.r11.tools.controller.internal.ScopedControllerManifest; |  | ||||||
| import com.r11.tools.xml.Xalan; |  | ||||||
| import com.r11.tools.xml.XmlEngine; | import com.r11.tools.xml.XmlEngine; | ||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
| import spark.Request; | import spark.Request; | ||||||
| @@ -26,57 +23,63 @@ public class XsdController implements RestController { | |||||||
|         this.xalan = xalan; |         this.xalan = xalan; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @ScopedControllerManifest(method = HandlerType.POST, path = "/xsd") |     private XMLResponseBody prepareErrorResponse(String message, String processor) { | ||||||
|     public Response transform(Request request, Response response) { |         return new XMLResponseBody(message, "ERR", processor, -1); | ||||||
|         String body = request.body(); |  | ||||||
|  |  | ||||||
|         JsonObject requestJson; |  | ||||||
|         try { |  | ||||||
|             requestJson = this.gson.fromJson(body, JsonObject.class); |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             JsonObject responseJson = new JsonObject(); |  | ||||||
|             responseJson.addProperty("result", e.getMessage()); |  | ||||||
|             responseJson.addProperty("processor", "N/A"); |  | ||||||
|             responseJson.addProperty("status", "ERR"); |  | ||||||
|             responseJson.addProperty("time", "N/A"); |  | ||||||
|  |  | ||||||
|             response.status(400); |  | ||||||
|             response.body(this.gson.toJson(responseJson)); |  | ||||||
|             return response; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|         String data = requestJson.get("data").getAsString(); |     private void nonValidEngineSelectedResponse(Response response) { | ||||||
|         String xsd = requestJson.get("process").getAsString(); |         XMLResponseBody responseBody = | ||||||
|  |                 prepareErrorResponse("Valid engines is: xalan", "N/A"); | ||||||
|         response.header("processor", xalan.getVersion()); |         response.body(this.gson.toJson(responseBody)); | ||||||
|  |         response.status(400); | ||||||
|         long timeStart = System.currentTimeMillis(); |     } | ||||||
|         String tmp; |     @ScopedControllerManifest(method = HandlerType.POST, path = "/xsd") | ||||||
|  |     public void acceptRequest(Request request, Response response) { | ||||||
|         JsonObject responseJson = new JsonObject(); |         XMLRequestBody requestBody; | ||||||
|         try { |         try { | ||||||
|             tmp = xalan.validate(data, xsd).trim(); |             requestBody = this.gson.fromJson(request.body(), XMLRequestBody.class); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             XMLResponseBody responseBody = prepareErrorResponse(e.getMessage(), "N/A"); | ||||||
|  |  | ||||||
|  |             response.status(400); | ||||||
|  |             response.body(this.gson.toJson(responseBody)); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (requestBody.getProcessor() == null) { | ||||||
|  |             nonValidEngineSelectedResponse(response); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if (requestBody.getProcessor().equalsIgnoreCase("xalan")) | ||||||
|  |             process(response, requestBody, xalan); | ||||||
|  |         else | ||||||
|  |             nonValidEngineSelectedResponse(response); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void process(Response response, XMLRequestBody requestBody, XmlEngine engine) { | ||||||
|  |         XMLResponseBody responseBody = null; | ||||||
|  |         try { | ||||||
|  |             long timeStart = System.currentTimeMillis(); | ||||||
|  |             String result = engine.validate(requestBody.getData(), requestBody.getProcess()).trim(); | ||||||
|  |  | ||||||
|             response.status(200); |             response.status(200); | ||||||
|  |  | ||||||
|             responseJson.addProperty("result", tmp); |             long duration = System.currentTimeMillis() - timeStart; | ||||||
|             responseJson.addProperty("status", "OK"); |             responseBody = new XMLResponseBody(result, "OK", engine.getVersion(), duration); | ||||||
|         } catch (Exception ex) { |  | ||||||
|             this.logger.error("Error on validation against XSD using Xalan. " + ex); |  | ||||||
|  |  | ||||||
|  |             this.logger.info("Request (XSD, " +  engine.getVersion() + ") processed in " + duration + " ms."); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             responseBody = prepareErrorResponse(ex.getMessage(), engine.getVersion()); | ||||||
|             response.status(400); |             response.status(400); | ||||||
|  |  | ||||||
|             responseJson.addProperty("result", ex.getMessage()); |             this.logger.error("Error on validation against XSD using " + engine.getVersion() + ". " + ex); | ||||||
|             responseJson.addProperty("status", "ERR"); |         } | ||||||
|  |         finally { | ||||||
|  |             response.body(this.gson.toJson(responseBody)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         long duration = System.currentTimeMillis() - timeStart; |  | ||||||
|         this.logger.info("Request (XSD, Xalan) processed in " + duration + " ms."); |  | ||||||
|  |  | ||||||
|         responseJson.addProperty("processor", xalan.getVersion()); |  | ||||||
|         responseJson.addProperty("time", duration); |  | ||||||
|  |  | ||||||
|         response.body(this.gson.toJson(responseJson)); |  | ||||||
|         return response; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,13 +1,9 @@ | |||||||
| package com.r11.tools.controller; | package com.r11.tools.controller; | ||||||
|  |  | ||||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||||
| import com.google.gson.JsonObject; | import com.r11.tools.controller.internal.*; | ||||||
| import com.r11.tools.controller.internal.GlobalControllerManifest; | import com.r11.tools.model.XMLRequestBody; | ||||||
| import com.r11.tools.controller.internal.HandlerType; | import com.r11.tools.model.XMLResponseBody; | ||||||
| import com.r11.tools.controller.internal.RestController; |  | ||||||
| import com.r11.tools.controller.internal.ScopedControllerManifest; |  | ||||||
| import com.r11.tools.xml.Saxon; |  | ||||||
| import com.r11.tools.xml.Xalan; |  | ||||||
| import com.r11.tools.xml.XmlEngine; | import com.r11.tools.xml.XmlEngine; | ||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
| import spark.Request; | import spark.Request; | ||||||
| @@ -29,106 +25,69 @@ public class XsltController implements RestController { | |||||||
|         this.xalan = xalan; |         this.xalan = xalan; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @ScopedControllerManifest(method = HandlerType.POST, path = "/xslt") |     private XMLResponseBody prepareErrorResponse(String message, String processor) { | ||||||
|     public void transform(Request request, Response response) { |         return new XMLResponseBody(message, "ERR", processor, -1); | ||||||
|         String body = request.body(); |     } | ||||||
|  |  | ||||||
|         JsonObject requestJson; |     private void nonValidEngineSelectedResponse(Response response) { | ||||||
|  |         XMLResponseBody responseBody = | ||||||
|  |                 prepareErrorResponse("Valid engines are: saxon, xalan", "N/A"); | ||||||
|  |         response.body(this.gson.toJson(responseBody)); | ||||||
|  |         response.status(400); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ScopedControllerManifest(method = HandlerType.POST, path = "/xslt") | ||||||
|  |     public void acceptRequest(Request request, Response response) { | ||||||
|  |         XMLRequestBody requestBody; | ||||||
|         try { |         try { | ||||||
|             requestJson = this.gson.fromJson(body, JsonObject.class); |             requestBody = this.gson.fromJson(request.body(), XMLRequestBody.class); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             JsonObject responseJson = new JsonObject(); |             XMLResponseBody responseBody = prepareErrorResponse(e.getMessage(), "N/A"); | ||||||
|             responseJson.addProperty("result", e.getMessage()); |  | ||||||
|             responseJson.addProperty("processor", "N/A"); |  | ||||||
|             responseJson.addProperty("status", "ERR"); |  | ||||||
|             responseJson.addProperty("time", "N/A"); |  | ||||||
|  |  | ||||||
|             response.status(400); |             response.status(400); | ||||||
|             response.body(this.gson.toJson(responseJson)); |             response.body(this.gson.toJson(responseBody)); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         String data = requestJson.get("data").getAsString(); |         if (requestBody.getProcessor() == null) { | ||||||
|         String query = requestJson.get("process").getAsString(); |             nonValidEngineSelectedResponse(response); | ||||||
|         String processor = requestJson.get("processor").getAsString(); |  | ||||||
|         String version = requestJson.get("version").getAsString(); |  | ||||||
|  |  | ||||||
|         if (processor == null) { |  | ||||||
|             response.body("saxon, xalan"); |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         JsonObject responseJson = new JsonObject(); |  | ||||||
|         switch (processor) { |         switch (requestBody.getProcessor()) { | ||||||
|             case "saxon": |             case "saxon": | ||||||
|                 processWithSaxon(response, data, query, version, responseJson); |                 process(response, requestBody, saxon); | ||||||
|                 return; |                 return; | ||||||
|  |  | ||||||
|             case "xalan": |             case "xalan": | ||||||
|                 processWithXalan(response, data, query, responseJson); |                 process(response, requestBody, xalan); | ||||||
|                 return; |                 return; | ||||||
|  |  | ||||||
|             default: |             default: | ||||||
|                 response.body("saxon, xalan"); |                 nonValidEngineSelectedResponse(response); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void processWithXalan(Response response, String data, String query, JsonObject responseJson) { |     private void process(Response response, XMLRequestBody requestBody, XmlEngine engine) { | ||||||
|         long duration; |         XMLResponseBody responseBody = null; | ||||||
|         long timeStart; |         long timeStart = System.currentTimeMillis(); | ||||||
|         String tmp; |  | ||||||
|         timeStart = System.currentTimeMillis(); |  | ||||||
|         try { |         try { | ||||||
|             tmp = xalan.processXSLT(data, query); |             String result = engine.processXSLT(requestBody.getData(), requestBody.getProcess()); | ||||||
|  |  | ||||||
|             response.status(200); |             response.status(200); | ||||||
|  |  | ||||||
|             responseJson.addProperty("result", tmp); |             long duration = System.currentTimeMillis() - timeStart; | ||||||
|             responseJson.addProperty("status", "OK"); |             responseBody = new XMLResponseBody(result, "OK", engine.getVersion(), duration); | ||||||
|  |  | ||||||
|  |             this.logger.info("Request (XSLT, " + engine.getVersion() + ") processed in " + duration + " ms."); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             this.logger.error("Error on processing XSLT using Xalan. " + ex); |             responseBody = prepareErrorResponse(ex.getMessage(), engine.getVersion()); | ||||||
|  |  | ||||||
|             response.status(400); |             response.status(400); | ||||||
|  |             this.logger.error("Error on processing XSLT using " + engine.getVersion() + ". " + ex); | ||||||
|  |  | ||||||
|             responseJson.addProperty("result", ex.getMessage()); |         } finally { | ||||||
|             responseJson.addProperty("status", "ERR"); |             response.body(this.gson.toJson(responseBody)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         duration = System.currentTimeMillis() - timeStart; |  | ||||||
|         this.logger.info("Request (XSLT, Xalan) processed in " + duration + " ms."); |  | ||||||
|  |  | ||||||
|         responseJson.addProperty("processor", xalan.getVersion()); |  | ||||||
|         responseJson.addProperty("time", duration); |  | ||||||
|  |  | ||||||
|         response.body(this.gson.toJson(responseJson)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void processWithSaxon(Response response, String data, String query, String version, JsonObject responseJson) { |  | ||||||
|         long duration; |  | ||||||
|         String tmp; |  | ||||||
|         long timeStart; |  | ||||||
|         timeStart = System.currentTimeMillis(); |  | ||||||
|         try { |  | ||||||
|             tmp = saxon.processXSLT(data, query); |  | ||||||
|  |  | ||||||
|             response.status(200); |  | ||||||
|  |  | ||||||
|             responseJson.addProperty("result", tmp); |  | ||||||
|             responseJson.addProperty("status", "OK"); |  | ||||||
|         } catch (Exception ex) { |  | ||||||
|             this.logger.error("Error on processing XSLT using Saxon. " + ex); |  | ||||||
|  |  | ||||||
|             response.status(400); |  | ||||||
|  |  | ||||||
|             responseJson.addProperty("result", ex.getMessage()); |  | ||||||
|             responseJson.addProperty("status", "ERR"); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         duration = System.currentTimeMillis() - timeStart; |  | ||||||
|         this.logger.info("Request (XSLT, Saxon) processed in " + duration + " ms."); |  | ||||||
|  |  | ||||||
|         responseJson.addProperty("processor", "Saxon " + saxon.getVersion() + " " + version); |  | ||||||
|         responseJson.addProperty("time", duration); |  | ||||||
|  |  | ||||||
|         response.body(this.gson.toJson(responseJson)); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,34 @@ | |||||||
|  | package com.r11.tools.model; | ||||||
|  |  | ||||||
|  | import com.google.gson.annotations.SerializedName; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * POJO class used to contain body of XML related requests | ||||||
|  |  * @author Adam | ||||||
|  |  */ | ||||||
|  | public class XMLRequestBody { | ||||||
|  |     @SerializedName("data") | ||||||
|  |     private String data; | ||||||
|  |     @SerializedName("process") | ||||||
|  |     private String process; | ||||||
|  |     @SerializedName("processor") | ||||||
|  |     private String processor; | ||||||
|  |     @SerializedName("version") | ||||||
|  |     private String version; | ||||||
|  |  | ||||||
|  |     public String getData() { | ||||||
|  |         return data; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getProcess() { | ||||||
|  |         return process; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getProcessor() { | ||||||
|  |         return processor; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getVersion() { | ||||||
|  |         return version; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,59 @@ | |||||||
|  | package com.r11.tools.model; | ||||||
|  |  | ||||||
|  | public class XMLResponseBody { | ||||||
|  |  | ||||||
|  |     private String result; | ||||||
|  |     private String status; | ||||||
|  |     private String processor; | ||||||
|  |     private long duration; | ||||||
|  |  | ||||||
|  |     // Optional | ||||||
|  |     private String type; | ||||||
|  |  | ||||||
|  |     public XMLResponseBody(String result, String status, String processor, long duration) { | ||||||
|  |         this.result = result; | ||||||
|  |         this.status = status; | ||||||
|  |         this.processor = processor; | ||||||
|  |         this.duration = duration; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getResult() { | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setResult(String result) { | ||||||
|  |         this.result = result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getStatus() { | ||||||
|  |         return status; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setStatus(String status) { | ||||||
|  |         this.status = status; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getProcessor() { | ||||||
|  |         return processor; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setProcessor(String processor) { | ||||||
|  |         this.processor = processor; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public long getDuration() { | ||||||
|  |         return duration; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setDuration(long duration) { | ||||||
|  |         this.duration = duration; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getType() { | ||||||
|  |         return type; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setType(String type) { | ||||||
|  |         this.type = type; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| package com.r11.tools.controller.internal; | package com.r11.tools.model; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Class used to store data received from parser and type of that data (node, string, etc.) |  * Class used to store data received from parser and type of that data (node, string, etc.) | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| package com.r11.tools.xml; | package com.r11.tools.xml; | ||||||
|  |  | ||||||
| import com.r11.tools.controller.internal.XPathQueryResult; | import com.r11.tools.model.XPathQueryResult; | ||||||
| import net.sf.saxon.s9api.*; | import net.sf.saxon.s9api.*; | ||||||
|  |  | ||||||
| import javax.xml.transform.stream.StreamSource; | import javax.xml.transform.stream.StreamSource; | ||||||
| @@ -39,6 +39,29 @@ public class Saxon implements XmlEngine{ | |||||||
|         throw new UnsupportedOperationException(); |         throw new UnsupportedOperationException(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * This method evaluates XQuery exporession on given xml | ||||||
|  |      * @param data xml | ||||||
|  |      * @param xquery expression | ||||||
|  |      * @return | ||||||
|  |      * @throws Exception | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public String executeXQuery(String data, String xquery, String version) throws Exception { | ||||||
|  |         Processor processor = new Processor(false); | ||||||
|  |  | ||||||
|  |         XQueryCompiler compiler = processor.newXQueryCompiler(); | ||||||
|  |         compiler.setLanguageVersion(version); | ||||||
|  |  | ||||||
|  |         XQueryExecutable executable = compiler.compile(xquery); | ||||||
|  |  | ||||||
|  |         XQueryEvaluator evaluator = executable.load(); | ||||||
|  |         evaluator.setSource(new StreamSource(new StringReader(data))); | ||||||
|  |  | ||||||
|  |         XdmValue result = evaluator.evaluate(); | ||||||
|  |         return result.toString(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Process xpath and return either node or wrapped atomic value |      * Process xpath and return either node or wrapped atomic value | ||||||
|      * @param data xml to be querried |      * @param data xml to be querried | ||||||
| @@ -76,6 +99,6 @@ public class Saxon implements XmlEngine{ | |||||||
|      * @return version of the processor |      * @return version of the processor | ||||||
|      */ |      */ | ||||||
|     public String getVersion() { |     public String getVersion() { | ||||||
|         return new Processor(false).getSaxonProductVersion(); |         return "Saxon " + new Processor(false).getSaxonProductVersion(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| package com.r11.tools.xml; | package com.r11.tools.xml; | ||||||
|  |  | ||||||
| import com.r11.tools.controller.internal.XPathQueryResult; | import com.r11.tools.model.XPathQueryResult; | ||||||
| import org.apache.xpath.XPathAPI; | import org.apache.xpath.XPathAPI; | ||||||
| import org.apache.xpath.objects.XObject; |  | ||||||
| import org.w3c.dom.Document; | import org.w3c.dom.Document; | ||||||
| import org.w3c.dom.Node; | import org.w3c.dom.Node; | ||||||
| import org.w3c.dom.traversal.NodeIterator; | import org.w3c.dom.traversal.NodeIterator; | ||||||
| @@ -133,4 +132,9 @@ public class Xalan implements XmlEngine{ | |||||||
|         validator.validate(dataSource); |         validator.validate(dataSource); | ||||||
|         return "XML file is valid"; |         return "XML file is valid"; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String executeXQuery(String data, String xquery, String version) throws Exception { | ||||||
|  |         throw new UnsupportedOperationException("Xalan doesn't support XQuery evaluation"); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,12 +1,14 @@ | |||||||
| package com.r11.tools.xml; | package com.r11.tools.xml; | ||||||
|  |  | ||||||
| import com.r11.tools.controller.internal.XPathQueryResult; | import com.r11.tools.model.XPathQueryResult; | ||||||
|  |  | ||||||
| public interface XmlEngine { | public interface XmlEngine { | ||||||
|     XPathQueryResult processXPath(String data, String query, String version) throws Exception; |     XPathQueryResult processXPath(String data, String query, String version) throws Exception; | ||||||
|     String processXSLT(String data, String transform) throws Exception; |     String processXSLT(String data, String transform) throws Exception; | ||||||
|     String validate(String data, String xsd) throws Exception; |     String validate(String data, String xsd) throws Exception; | ||||||
|  |  | ||||||
|  |     String executeXQuery(String data, String xquery, String version) throws Exception; | ||||||
|  |  | ||||||
|     public String getVersion(); |     public String getVersion(); | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								Frontend/assets/samples/sampleXQuery.xquery
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Frontend/assets/samples/sampleXQuery.xquery
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | declare namespace p="http://www.release11.com/person"; | ||||||
|  | declare namespace b="http://www.release11.com/book"; | ||||||
|  | declare namespace l="http://www.release11.com/library"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | for $x in //p:person | ||||||
|  | return string($x/p:name) | ||||||
| @@ -25,6 +25,7 @@ function init() { | |||||||
|     tools.set("xpath", "tools/xpath.html"); |     tools.set("xpath", "tools/xpath.html"); | ||||||
|     tools.set("xsd", "tools/xsd.html"); |     tools.set("xsd", "tools/xsd.html"); | ||||||
|     tools.set("xslt", "tools/xslt.html"); |     tools.set("xslt", "tools/xslt.html"); | ||||||
|  |     tools.set("xquery", "tools/xquery.html"); | ||||||
|     tools.set("xmlform", "tools/xmlFormatter.html"); |     tools.set("xmlform", "tools/xmlFormatter.html"); | ||||||
|     tools.set("jsonform", "tools/jsonFormatter.html"); |     tools.set("jsonform", "tools/jsonFormatter.html"); | ||||||
|     tools.set("mock", "tools/mock.html"); |     tools.set("mock", "tools/mock.html"); | ||||||
|   | |||||||
| @@ -135,6 +135,24 @@ function fillDefaultXSLT() { | |||||||
|         } )    |         } )    | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The `fillDefaultXQuery()` function fetches a default XQuery from the server and sets the value of the element with id "transformArea" to the fetched template. | ||||||
|  |  *  | ||||||
|  |  * @function | ||||||
|  |  * @name fillDefaultXQuery | ||||||
|  |  * @kind function | ||||||
|  |  * @returns {void} | ||||||
|  |  */ | ||||||
|  | function fillDefaultXQuery() { | ||||||
|  |     const serverAddress = window.location.protocol + "//" + window.location.hostname; | ||||||
|  |     fetch(serverAddress + "/assets/samples/sampleXQuery.xquery") | ||||||
|  |         .then( response => response.text() ) | ||||||
|  |         .then( (XQueryTemplate) => { | ||||||
|  |             document.getElementById('transformArea').innerText = XQueryTemplate; | ||||||
|  |             highlightSyntax("transformArea"); | ||||||
|  |         } )    | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
| * It sets default content for the element an changes it's color to grey | * It sets default content for the element an changes it's color to grey | ||||||
| *  | *  | ||||||
| @@ -300,7 +318,7 @@ function performRequest(endpoint, checkXML, checkTransform) { | |||||||
|              |              | ||||||
|                  |                  | ||||||
|             if (result.status == "OK") { |             if (result.status == "OK") { | ||||||
|                 document.getElementById("procinfo").innerText += " (" + result.time + "ms)"; |                 document.getElementById("procinfo").innerText += " (" + result.duration + "ms)"; | ||||||
|                 if (result.type) |                 if (result.type) | ||||||
|                     document.getElementById("procinfo").innerText += ". Returned: " + result.type; |                     document.getElementById("procinfo").innerText += ". Returned: " + result.type; | ||||||
|                 else |                 else | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								Frontend/assets/scripts/tools/xquery.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Frontend/assets/scripts/tools/xquery.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | /** | ||||||
|  |  * This function is executed after the page is loaded. | ||||||
|  |  *  | ||||||
|  |  * @function | ||||||
|  |  * @name init | ||||||
|  |  * @kind function | ||||||
|  |  */ | ||||||
|  | function init() { | ||||||
|  |     // Make sure that only plain text is pasted | ||||||
|  |     configurePastingInElement("xmlArea"); | ||||||
|  |     configurePastingInElement("transformArea"); | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -36,6 +36,7 @@ | |||||||
|                 <li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xpath');">XPath</a></li> |                 <li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xpath');">XPath</a></li> | ||||||
|                 <li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xslt');">XSLT</a></li> |                 <li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xslt');">XSLT</a></li> | ||||||
|                 <li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xsd');">XSD</a></li> |                 <li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xsd');">XSD</a></li> | ||||||
|  |                 <li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xquery');">XQuery</a></li> | ||||||
|                 <li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xmlform');">XML Formatter</a></li> |                 <li class="toolListRow xmlTool"><a href="#" onclick="changeTool('xmlform');">XML Formatter</a></li> | ||||||
|                 <li class="toolListRow jsonTool"><a href="#" onclick="changeTool('jsonform');">JSON Formatter</a></li> |                 <li class="toolListRow jsonTool"><a href="#" onclick="changeTool('jsonform');">JSON Formatter</a></li> | ||||||
|             </ul> |             </ul> | ||||||
|   | |||||||
							
								
								
									
										87
									
								
								Frontend/tools/xquery.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								Frontend/tools/xquery.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  |  | ||||||
|  | <head> | ||||||
|  |     <!-- <link rel="stylesheet" href="styles.css"> --> | ||||||
|  |     <link rel="stylesheet" href="../assets/css/tools/r11form.css"> | ||||||
|  |     <link rel="stylesheet" href="../assets/css/highlight.css"> | ||||||
|  |     <script src="../assets/scripts/common/hljs.min.js"></script> | ||||||
|  |     <script src="../assets/scripts/tools/xquery.js"></script> | ||||||
|  |     <script src="../assets/scripts/tools/scripts.js"></script> | ||||||
|  |     <script src="../assets/scripts/tools/highlight.js"></script> | ||||||
|  |     <script>hljs.highlightAll();</script> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <meta charset="utf-8" /> | ||||||
|  | </head> | ||||||
|  |  | ||||||
|  | <body onload="init();"> | ||||||
|  |     <div class="container"> | ||||||
|  |         <div id="tool" class="tool rwd-expandable"> | ||||||
|  |             <div class="tool-context"> | ||||||
|  |                 <div class="headline"> | ||||||
|  |                     <h1>Online XQuery Interpreter</h1> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="display-space-between"> | ||||||
|  |                     <div style="text-align: center;"> | ||||||
|  |                         <label for="processors">Select XQuery processor:</label> | ||||||
|  |                         <select name="processors" id="processors"> | ||||||
|  |                             <option value="saxon">Saxon</option> | ||||||
|  |                         </select> | ||||||
|  |                         <label for="versions">XQuery version:</label> | ||||||
|  |                         <select name="versions" id="versions"> | ||||||
|  |                             <option class="hideable saxon" value="3.1">3.1</option> | ||||||
|  |                             <option class="hideable saxon" value="4.0">4.0</option> | ||||||
|  |                         </select> | ||||||
|  |                     </div> | ||||||
|  |                     <div> | ||||||
|  |                         <button class="action-button active" id="clearXMLButton" style="padding: 3px 10px;" | ||||||
|  |                             onclick="clearDataField()">Clear</button> | ||||||
|  |                         <button class="action-button active" id="prettyXMLButton" style="padding: 3px 10px;" | ||||||
|  |                             onclick="performFormatRequest('prettify', true, 'xmlArea', 'xmlArea')">Format XML</button> | ||||||
|  |                         <button class="action-button active" id="defaultXMLButton" style="padding: 3px 10px;" | ||||||
|  |                             onclick="fillDefaultXML(this)">Insert default XML</button> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |  | ||||||
|  |                 <span id="processorTooltipInfo">Supports XQuery up to 4.0</span><br> | ||||||
|  |                 <br> | ||||||
|  |  | ||||||
|  |                 <label for="xmlArea"><b>Insert your XML:</b></label> | ||||||
|  |                 <pre><code class="language-xml bordered-field textarea-300" id="xmlArea" contenteditable="True"></code></pre> | ||||||
|  |                 <br> | ||||||
|  |  | ||||||
|  |                 <div class="display-space-between"> | ||||||
|  |                     <label for="transformArea"><b>Insert your XQuery:</b></label> | ||||||
|  |                     <div> | ||||||
|  |                         <button class="action-button active" id="defaultQueryButton" style="padding: 3px 10px;" onclick="fillDefaultXQuery();">Insert default XQuery</button> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |                 <pre><code class="language-xml bordered-field textarea-300" id="transformArea" contenteditable="True"></code></pre> | ||||||
|  |                 <br> | ||||||
|  |                 <button id="requestButton" class="max-width block-label action-button active" | ||||||
|  |                     onclick="performRequest('xquery', true, true)">Execute XQuery</button> | ||||||
|  |                 <br> | ||||||
|  |  | ||||||
|  |                 <label for="resultArea"><b>Query result:<span id="procinfo"></span></b></label> | ||||||
|  |                 <pre><code class="language-xml bordered-field textarea-300" id="resultArea"></code></pre> | ||||||
|  |  | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="tooltip tooltip-window rwd-hideable"> | ||||||
|  |             <h2>What is XQuery?</h2> | ||||||
|  |             <p><b>XQuery</b> (<b>XML Query</b>) is a query and functional programming language that queries and transforms collections of structured and unstructured data, usually in the form of XML, text and with vendor-specific extensions for other data formats (JSON, binary, etc.).</p> | ||||||
|  |             <p>Source: <a href="https://en.wikipedia.org/wiki/XQuery">Wikipedia</a></p> | ||||||
|  |         </div> | ||||||
|  |  | ||||||
|  |         <!-- Cut END --> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  | </body> | ||||||
|  |  | ||||||
|  | </html> | ||||||
							
								
								
									
										33
									
								
								Samples/xquery/sampleXML.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Samples/xquery/sampleXML.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <l:library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.release11.com" xmlns:l="http://www.release11.com/library" xmlns:p="http://www.release11.com/person" xmlns:b="http://www.release11.com/book"> | ||||||
|  |     <l:libraryName>City library</l:libraryName> | ||||||
|  |     <l:libraryID>345123</l:libraryID> | ||||||
|  |     <l:readerList> | ||||||
|  |         <p:person> | ||||||
|  |             <p:readerID>7321</p:readerID> | ||||||
|  |             <p:name>Adam</p:name> | ||||||
|  |             <p:surname>Choke</p:surname> | ||||||
|  |         </p:person> | ||||||
|  |         <p:person> | ||||||
|  |             <p:readerID>5123</p:readerID> | ||||||
|  |             <p:name>Lauren</p:name> | ||||||
|  |             <p:surname>Wong</p:surname> | ||||||
|  |         </p:person> | ||||||
|  |     </l:readerList> | ||||||
|  |     <l:bookList> | ||||||
|  |         <b:book> | ||||||
|  |             <b:bookID>6422</b:bookID> | ||||||
|  |             <b:title>Harry Potter</b:title> | ||||||
|  |             <p:readerID>7542</p:readerID> | ||||||
|  |         </b:book> | ||||||
|  |         <b:book> | ||||||
|  |             <b:bookID>1234</b:bookID> | ||||||
|  |             <b:title>Macbeth</b:title> | ||||||
|  |             <p:readerID>5123</p:readerID> | ||||||
|  |         </b:book> | ||||||
|  |         <b:book> | ||||||
|  |             <b:bookID>9556</b:bookID> | ||||||
|  |             <b:title>Romeo and Juliet</b:title> | ||||||
|  |         </b:book> | ||||||
|  |     </l:bookList> | ||||||
|  | </l:library> | ||||||
							
								
								
									
										4
									
								
								Samples/xquery/xquery.curl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								Samples/xquery/xquery.curl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | url = "localhost/java/xquery" | ||||||
|  | #url = "localhost/libxml/xslt" | ||||||
|  | data = "@xquery.json" | ||||||
|  | request = POST | ||||||
							
								
								
									
										6
									
								
								Samples/xquery/xquery.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Samples/xquery/xquery.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "data": "<people><person><name>John</name><age>67</age></person><person><name>Anna</name><age>69</age></person></people>", | ||||||
|  |     "process": "for $x in //person return string($x/name)", | ||||||
|  |     "processor": "saxon", | ||||||
|  |     "version": "3.1" | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user