diff --git a/Backend-libXML/Parser.py b/Backend-libXML/Parser.py index c652212..295b924 100644 --- a/Backend-libXML/Parser.py +++ b/Backend-libXML/Parser.py @@ -1,16 +1,32 @@ from lxml import etree +def prettify(source: str) -> str: + xml = etree.XML(source) + return etree.tostring(xml, pretty_print=True).decode() + +def minimize(source: str) -> str: + result = source + + to_remove = [" ", " ", "\t", "\n"] + to_substitute = [(" <", "<"), ("> ", ">"), ("", ">")] + + for chars in to_remove: + result = result.replace(chars, "") + + for e in to_substitute: + result = result.replace(e[0], e[1]) + + return result + + def xpath(source: str, xpath: str) -> str: """ Method used to get nodes from XML string using XPath :param source: XML string used for selection - :type source: str :param xpath: XPath query used for selection - :type xpath: str :return: Nodes selected using XPath - :rtype: str """ @@ -34,11 +50,8 @@ def xsd(source: str, xsd: str) -> bool: """ Method used to validate XML string against XSD schema :param source: XML string used for validation - :type source: str :param xsd: XSD schema to validate XML against - :type xsd: str :return: Message saying, if the validation was successful or not - :rtype: str """ xml_schema = etree.XMLSchema(etree.XML(xsd)) @@ -54,11 +67,8 @@ def xslt(source: str, xslt: str) -> str: Method used to transformate XML string using XSLT :param source: XML string to transform - :type source: str :param xslt: XSLT string used to transformate XML - :type xslt: str :return: Result of transformation - :rtype: str """ xslt_transform = etree.XSLT(etree.XML(xslt)) diff --git a/Backend-libXML/main.py b/Backend-libXML/main.py index 0869a00..55582cd 100644 --- a/Backend-libXML/main.py +++ b/Backend-libXML/main.py @@ -15,16 +15,50 @@ cors = CORS(app, resource={ } }) +def format_xml(request: request, type: str) -> str: + """Function to format XML + + :param request: Received request + :param type: Type of needed processing: xsd, xslt or xpath + :raises ValueError: is raised when type is different than those provided above + :return: response JSON converted to string and response code + """ + start = time.time_ns() + code = 200 + response_json = dict() + try: + request_data = json.loads(request.get_data(as_text=True)) + data = request_data['data'] + process = request_data['process'] + if (type == "prettify"): + response_json['result'] = Parser.xsd(data, process) + elif (type == "minimize"): + response_json['result'] = Parser.xslt(data, process) + else: + raise ValueError("Valid operation types are: prettify, minimize") + + response_json['status'] = "OK" + except KeyError as e: + response_json['result'] = "Missing key: " + str(e) + response_json['status'] = "ERR" + code = 400 + except Exception as e: + response_json['result'] = str(e) + response_json['status'] = "ERR" + code = 400 + finally: + exec_time = (time.time_ns() - start) / 10**6 + response_json['time'] = f"{exec_time:.03f}" + response_json['processor'] = "libxml2 over lxml" + return json.dumps(response_json), code + def process_xml(request: request, type: str) -> str: """Function to process :param request: Received request - :type request: request :param type: Type of needed processing: xsd, xslt or xpath - :type type: str :raises ValueError: is raised when type is different than those provided above :return: response JSON converted to string and response code - :rtype: str, int """ start = time.time_ns() code = 200 @@ -39,6 +73,10 @@ def process_xml(request: request, type: str) -> str: response_json['result'] = Parser.xslt(data, process) elif (type == "xpath"): response_json['result'] = Parser.xpath(data, process) + elif (type == "prettify"): + response_json['result'] = Parser.prettify(data) + elif (type == "minimize"): + response_json['result'] = Parser.minimize(data) else: raise ValueError("Valid operation types are: xsd, xslt, xpath") @@ -70,5 +108,13 @@ def xsd(): def xslt(): return process_xml(request, "xslt") +@app.route("/prettifypost", methods=["POST"]) +def prettify(): + return process_xml(request, "prettify") + +@app.route("/minimizepost", methods=["POST"]) +def minimize(): + return process_xml(request, "minimize") + if __name__ == "__main__": app.run() \ No newline at end of file diff --git a/Backend-libXML/sample/minimize/minimize.curl b/Backend-libXML/sample/minimize/minimize.curl new file mode 100644 index 0000000..f75d62a --- /dev/null +++ b/Backend-libXML/sample/minimize/minimize.curl @@ -0,0 +1,3 @@ +url = "http://localhost:5000/minimizepost" +data = "@minimize.json" +request = POST diff --git a/Backend-libXML/sample/minimize/minimize.json b/Backend-libXML/sample/minimize/minimize.json new file mode 100644 index 0000000..10bfc79 --- /dev/null +++ b/Backend-libXML/sample/minimize/minimize.json @@ -0,0 +1,5 @@ +{ + "data": "Hamlet2001-05-041falseMacbeth2000-12-131falseHarry Potter and the Sorcerer's Stone2005-04-292trueThe Long Walk2018-07-014trueMisery2018-01-314trueThink and Grow Rich2004-09-106trueThe Law of Success1982-05-096falsePatriot Games1995-10-215falseThe Sum of All Fears1992-09-195falseThe Alchemist2017-02-203falseHamlet1994-06-011falseMeasure for Measure1990-03-231falseHamlet1989-05-051trueHamlet1999-05-301trueThe Law of Success2004-11-266trueRomeo and Juliet1997-02-081trueThe Alchemist2009-08-213true", + "processor": "libxml", + "version": "1.0" +} diff --git a/Backend-libXML/sample/minimize/pretty b/Backend-libXML/sample/minimize/pretty new file mode 100644 index 0000000..7690e96 --- /dev/null +++ b/Backend-libXML/sample/minimize/pretty @@ -0,0 +1,104 @@ + + + Hamlet + 2001-05-04 + 1 + false + + + Macbeth + 2000-12-13 + 1 + false + + + Harry Potter and the Sorcerer's Stone + 2005-04-29 + 2 + true + + + The Long Walk + 2018-07-01 + 4 + true + + + Misery + 2018-01-31 + 4 + true + + + Think and Grow Rich + 2004-09-10 + 6 + true + + + The Law of Success + 1982-05-09 + 6 + false + + + Patriot Games + 1995-10-21 + 5 + false + + + The Sum of All Fears + 1992-09-19 + 5 + false + + + The Alchemist + 2017-02-20 + 3 + false + + + Hamlet + 1994-06-01 + 1 + false + + + Measure for Measure + 1990-03-23 + 1 + false + + + Hamlet + 1989-05-05 + 1 + true + + + Hamlet + 1999-05-30 + 1 + true + + + The Law of Success + 2004-11-26 + 6 + true + + + Romeo and Juliet + 1997-02-08 + 1 + true + + + The Alchemist + 2009-08-21 + 3 + true + + diff --git a/Backend-libXML/sample/prettify/prettify.curl b/Backend-libXML/sample/prettify/prettify.curl new file mode 100644 index 0000000..643474d --- /dev/null +++ b/Backend-libXML/sample/prettify/prettify.curl @@ -0,0 +1,3 @@ +url = "http://localhost:5000/prettifypost" +data = "@prettify.json" +request = POST diff --git a/Backend-libXML/sample/prettify/prettify.json b/Backend-libXML/sample/prettify/prettify.json new file mode 100644 index 0000000..cb3a5ec --- /dev/null +++ b/Backend-libXML/sample/prettify/prettify.json @@ -0,0 +1,6 @@ +{ + "data": "Hamlet2001-05-041falseMacbeth2000-12-131falseHarry Potter and the Sorcerer's Stone2005-04-292trueThe Long Walk2018-07-014trueMisery2018-01-314trueThink and Grow Rich2004-09-106trueThe Law of Success1982-05-096falsePatriot Games1995-10-215falseThe Sum of All Fears1992-09-195falseThe Alchemist2017-02-203falseHamlet1994-06-011falseMeasure for Measure1990-03-231falseHamlet1989-05-051trueHamlet1999-05-301trueThe Law of Success2004-11-266trueRomeo and Juliet1997-02-081trueThe Alchemist2009-08-213true", + "process": "whatever", + "processor": "libxml", + "version": "1.0" +} diff --git a/Backend-libXML/sample/xpath/non-ns.curl b/Backend-libXML/sample/xpath/non-ns.curl index 7d4219f..b059ae6 100644 --- a/Backend-libXML/sample/xpath/non-ns.curl +++ b/Backend-libXML/sample/xpath/non-ns.curl @@ -1,4 +1,4 @@ #url = "localhost:8081/xpathpost" -url = "localhost:5000/xpath" +url = "localhost:5000/xpathpost" request = "POST" data = "@data.json" diff --git a/Backend-libXML/sample/xpath/ns.curl b/Backend-libXML/sample/xpath/ns.curl index f439c0e..90af030 100644 --- a/Backend-libXML/sample/xpath/ns.curl +++ b/Backend-libXML/sample/xpath/ns.curl @@ -1,4 +1,4 @@ #url = "localhost:8081/xpathpost" -url = "localhost:5000/xpath" +url = "localhost:5000/xpathpost" request = "POST" data = "@dataNS.json" diff --git a/Backend-libXML/sample/xsd/xsd.curl b/Backend-libXML/sample/xsd/xsd.curl index 2481c02..ae731a5 100644 --- a/Backend-libXML/sample/xsd/xsd.curl +++ b/Backend-libXML/sample/xsd/xsd.curl @@ -1,4 +1,4 @@ -#url = "http://localhost:8082/xsd" -url = "http://localhost:5000/xsd" +#url = "http://localhost:8082/xsdpost" +url = "http://localhost:5000/xsdpost" data = "@xsd.json" request = POST diff --git a/Backend-libXML/sample/xslt/xslt.curl b/Backend-libXML/sample/xslt/xslt.curl index d50edd1..a7a6f94 100644 --- a/Backend-libXML/sample/xslt/xslt.curl +++ b/Backend-libXML/sample/xslt/xslt.curl @@ -1,3 +1,3 @@ -url = "http://localhost:5000/xslt" +url = "http://localhost:5000/xsltpost" data = "@xslt.json" request = POST diff --git a/Backend/mocked-services/src/main/resources/static/html/mock.html b/Backend/mocked-services/src/main/resources/static/html/mock.html index d844052..a908ea5 100644 --- a/Backend/mocked-services/src/main/resources/static/html/mock.html +++ b/Backend/mocked-services/src/main/resources/static/html/mock.html @@ -34,15 +34,16 @@
- - + + + +
diff --git a/Backend/mocked-services/src/main/resources/static/js/datatransfer.js b/Backend/mocked-services/src/main/resources/static/js/datatransfer.js index 55eda14..1a042d5 100644 --- a/Backend/mocked-services/src/main/resources/static/js/datatransfer.js +++ b/Backend/mocked-services/src/main/resources/static/js/datatransfer.js @@ -13,6 +13,10 @@ const removeMessageName = 'removeMessage'; const C_UUID = 'mock-uuid'; const C_ID = 'last-displayed-id'; const C_ADV = 'advanced-mode'; + +const color_red = "#ff8f8f"; +const color_grey = "#6b6b6b"; + const setModified = function(){ setDataModified(); } @@ -41,7 +45,6 @@ function getData(){ } - function checkUuid(){ if(clientUUID == null || clientUUID == undefined || clientUUID == ''){ clientUUID = json[0].clientUUID; @@ -56,11 +59,22 @@ function getDomain(){ return result; } +function httpStatusInvalid(){ + value = $('#httpStatus').val(); + return value == ''; +} + function setDataModified(){ - if(dataModified) return; + if(httpStatusInvalid()){ + $('#btn-save').removeClass('active'); + $('#btn-save').off(); + document.getElementById("httpStatus").style.backgroundColor = color_red; + return; + } dataModified = true; $('#btn-save').addClass('active'); $('#btn-save').click(getUpdate); + document.getElementById("httpStatus").style.backgroundColor = null; } //Adding change listener to fields @@ -198,13 +212,13 @@ function clearMock(){ } function initializeMock(index){ - clearMock(); - fillStaticFields(json[index].clientUUID - , json[index].mockedResponseId - , json[index].mediaType - , json[index].messageBody - , json[index].httpStatus); - fillHeaderTable(json[index].httpHeaders); + clearMock(); + fillStaticFields(json[index].clientUUID + , json[index].mockedResponseId + , json[index].mediaType + , json[index].messageBody + , json[index].httpStatus); + fillHeaderTable(json[index].httpHeaders); } function fillStaticFields(uuid, id, mediaType, body, httpStatus){ diff --git a/Frontend/assets/css/tools/r11form.css b/Frontend/assets/css/tools/r11form.css index f4af46e..6eb8ab9 100644 --- a/Frontend/assets/css/tools/r11form.css +++ b/Frontend/assets/css/tools/r11form.css @@ -20,7 +20,7 @@ padding: 15px 30px; font-family: 'Nunito', sans-serif; width: 30%; - height: 100%; + height: calc(100% - 25px); overflow: scroll; } @@ -287,6 +287,10 @@ width: 100%; } +.half-width { + width: 50%; +} + .max-width.with-padding { width: 94%; } @@ -437,10 +441,6 @@ content: "▼"; } -.content.active{ - -} - .hiddable { display: none; } @@ -479,6 +479,16 @@ textarea { box-sizing: border-box; } -code{ +code { line-height: 150%; +} + +@media only screen and (max-width: 768px) { + .rwd-hideable { + display: none; + } + + .rwd-expandable { + width: 100%; + } } \ No newline at end of file diff --git a/Frontend/assets/scripts/tools/scripts.js b/Frontend/assets/scripts/tools/scripts.js index 8792bc5..6becf43 100644 --- a/Frontend/assets/scripts/tools/scripts.js +++ b/Frontend/assets/scripts/tools/scripts.js @@ -91,7 +91,7 @@ function refreshTooltip() { document.getElementById("xsltelementsheader").innerText = XSLTheader; } -function performRequest(text, checkXML, checkTransform){ +function performRequest(endpoint, checkXML, checkTransform){ var xmlData = document.getElementById("xmlArea").value.trim(); var transformData = document.getElementById("transformArea").value.trim(); @@ -106,7 +106,7 @@ function performRequest(text, checkXML, checkTransform){ empty = true; } if (!empty) { - restRequest(text); + restRequest(endpoint, xmlData, transformData); }else{ document.getElementById("resultArea").value = "No data provided!"; return false; @@ -114,17 +114,33 @@ function performRequest(text, checkXML, checkTransform){ } +function performFormatRequest(endpoint, checkXML){ + var xmlData = document.getElementById("xmlArea").value.trim(); + + var empty = false; + if (defaultStrings.includes(xmlData) && checkXML) { + document.getElementById("xmlArea").style.backgroundColor = color_red; + xmlData = ""; + empty = true; + } + if (!empty) { + restRequest(endpoint, xmlData, null); + }else{ + document.getElementById("resultArea").value = "No data provided!"; + return false; + } + +} + + //Form REST request, send, receive and display in resultArea -async function restRequest(text) { +async function restRequest(endpoint, xmlData, transformData) { const escapeChar = "specialEscapeChar"; var port = ":8081/" if (getProcessor() == "libxml") { port = ":8082/" } - const addr = window.location.protocol + "//" + window.location.hostname + port + text; - - var xmlData = document.getElementById("xmlArea").value.trim(); - var transformData = document.getElementById("transformArea").value.trim(); + const addr = window.location.protocol + "//" + window.location.hostname + port + endpoint; if(defaultStrings.includes(xmlData)){ xmlData = ""; diff --git a/Frontend/index.html b/Frontend/index.html index 162acd4..d9d0cd2 100644 --- a/Frontend/index.html +++ b/Frontend/index.html @@ -25,6 +25,7 @@
  • XPath
  • XSLT
  • XSD
  • +
  • Formatter
  • diff --git a/Frontend/tools/formatter.html b/Frontend/tools/formatter.html new file mode 100644 index 0000000..c5d88f6 --- /dev/null +++ b/Frontend/tools/formatter.html @@ -0,0 +1,161 @@ + + + + + + + + + + + + +
    +
    +
    +
    +

    Online XML Formatter v0.21.37 BETA +

    +
    + + + + + +

    + + +

    + + + + +
    +
    +
    +

    What is this?

    +

    This tool has 2 main functions: +

    +

    +
    + + + +
    + + + + + + + + + + + + + + diff --git a/Frontend/tools/xpath.html b/Frontend/tools/xpath.html index 776cc66..14deda7 100644 --- a/Frontend/tools/xpath.html +++ b/Frontend/tools/xpath.html @@ -7,13 +7,14 @@ +
    -
    +

    Online XPath tester v0.4

    @@ -61,19 +62,21 @@
    -
    +

    What is XPath?

    -

    XPath is a querry language used for selecting nodes from XML and processing them.
    +

    XPath is a query language used for selecting nodes from XML and processing them.
    It may perform operations on strings, numbers and boolean values.

    - + + +

    XPath 2.0 introduced many new features XQuery-cośtam:
    - Added support for all XML simple types
    - - Many new functions (trippled instruction count)
    + - Many new functions (tripled instruction count)
    - All expressions evaluate to sequence
    - Introduces conditional expressions and for-loops

    @@ -81,14 +84,14 @@ - Dynamic function calls (function may be called without being referenced by name (find function in collection and call)
    - Inline functions
    - - Namespace literals - Namespace may be embeded into function name
    + - Namespace literals - Namespace may be embedded into function name
    - Support for union types - collections containing elements of different types
    - Mapping operator - '!' performs evaluation for each element in sequence and concatenates results
    - Introduced maps

    XPath 3.1
    - - New operator for function chaing '=>'
    + - New operator for function chaining '=>'
    - Introduced maps that store data in pair 'key:value' - 'map{ key : value, key : value }'
    - Introduced arrays - they differ from sequences in that they can be nested 'array{1, 5, 7, @@ -105,7 +108,9 @@

    - + + +
    @@ -334,7 +339,9 @@
    - + + +
    @@ -1244,7 +1251,9 @@
    - + + +
    @@ -1698,7 +1707,9 @@
    - + + +
    @@ -2602,7 +2613,9 @@
    + +
    @@ -2669,7 +2682,9 @@
    - + + +
    @@ -2990,71 +3005,76 @@
    -
    -
    +
    + + +
    + -
    - - - [3.0] fn:for-each(sequence*, function) +
    -
    - Applies function item to every element in sequence
    -
    - W3C Documentation reference: #func-for-each -
    -
    - + + [3.0] fn:for-each(sequence*, function) +
    +
    + Applies function item to every element in sequence
    +
    + W3C Documentation reference: #func-for-each +
    +
    +
    - - [3.0] fn:for-each-pair(sequence*, sequence*, function) -
    -
    - Applies the function to consecutive pairs of elements taken from sequences
    -
    - W3C Documentation reference: #func-for-each-pair -
    -
    -
    + + [3.0] fn:for-each-pair(sequence*, sequence*, function) +
    +
    + Applies the function to consecutive pairs of elements taken from sequences
    +
    + W3C Documentation reference: #func-for-each-pair +
    +
    +
    - - [3.0] fn:fold-left(sequence*, baseValue, function) -
    -
    - Applies function item to every element in sequence, accumulating value
    -
    - W3C Documentation reference: #func-fold-left -
    -
    -
    + + [3.0] fn:fold-left(sequence*, baseValue, function) +
    +
    + Applies function item to every element in sequence, accumulating value
    +
    + W3C Documentation reference: #func-fold-left +
    +
    +
    - - [3.0] fn:fold-right() -
    -
    - Applies function item to every element in sequence, accumulating value
    -
    - W3C Documentation reference: #func-fold-right -
    -
    -
    + + [3.0] fn:fold-right() +
    +
    + Applies function item to every element in sequence, accumulating value
    +
    + W3C Documentation reference: #func-fold-right +
    +
    +
    - - [3.0] fn:filter(sequence*, function) -
    -
    - Returns those items from the sequence for which the supplied function returns true
    -
    - W3C Documentation reference: #func-filter -
    + + [3.0] fn:filter(sequence*, function) +
    +
    + Returns those items from the sequence for which the supplied function returns true
    +
    + W3C Documentation reference: #func-filter +
    +
    +
    -
    +
    @@ -3100,18 +3120,28 @@ if (filter == "collapse3.0") { - showList(document.getElementsByName("collapse30")); document.getElementById("tooltipFunctionInfo").innerText = "XPath 1.0, 2.0 & 3.0 functions"; - // hideList(document.getElementsByName("collapse31")); + showList(document.getElementsByName("collapse20")); + showList(document.getElementsByName("collapse30")); + hideList(document.getElementsByName("collapse31")); console.log("collapsed 3.0"); } else if (filter == "collapse3.1") { - showList(document.getElementsByName("collapse31")); document.getElementById("tooltipFunctionInfo").innerText = "XPath 1.0, 2.0, 3.0 & 3.1 functions"; + showList(document.getElementsByName("collapse20")); + showList(document.getElementsByName("collapse30")); + showList(document.getElementsByName("collapse31")); console.log("collapsed 3.1"); - } else { + } else if (filter == "collapse2.0"){ document.getElementById("tooltipFunctionInfo").innerText = "XPath 1.0 & 2.0 functions"; + showList(document.getElementsByName("collapse20")); hideList(document.getElementsByName("collapse30")); hideList(document.getElementsByName("collapse31")); + } else { + document.getElementById("tooltipFunctionInfo").innerText = "XPath 1.0 functions"; + hideList(document.getElementsByName("collapse20")); + hideList(document.getElementsByName("collapse30")); + hideList(document.getElementsByName("collapse31")); + } @@ -3151,7 +3181,14 @@ console.log("trigger connected"); triggerList[i].addEventListener("click", function () { var collapsible = this.parentElement; - var collapsibleData = this.nextElementSibling; + if (this.tagName == "A") { + var collapsibleData = this.nextElementSibling; + } else { + var collapsibleData = this.parentElement.nextElementSibling; + + } + + console.log(collapsibleData); if (collapsibleData.style.maxHeight > "0px") { collapsibleData.style.maxHeight = "0px"; @@ -3193,14 +3230,14 @@ setDefaultContent(document.getElementById("xmlArea"), 'Insert XML here'); setDefaultContent(document.getElementById("transformArea"), 'Insert XPath expression here'); console.log("init"); - processTooltip(); processVersionSelector(); + processTooltip(); tool.addEventListener('change', event => { //Check if script was called from textarea or selector var targetID = event.target.getAttribute('id'); if (targetID == "processors") { - processTooltip(); processVersionSelector(); + processTooltip(); } else if (targetID == "versions") { processTooltip(); @@ -3215,7 +3252,7 @@ return; } processTooltip(); - processVersionSelector(); + }) tool.addEventListener('change', event => { //Check if script was called from textarea or selector @@ -3224,7 +3261,6 @@ return; } processTooltip(); - processVersionSelector(); }) } diff --git a/Frontend/tools/xsd.html b/Frontend/tools/xsd.html index 84234bf..47e6505 100644 --- a/Frontend/tools/xsd.html +++ b/Frontend/tools/xsd.html @@ -5,24 +5,31 @@ +
    -
    +

    Online XSD tester v0.4 BETA

    +
    +
    +
    + +
    + -