Implemented XML Formatter and simplified structure of XML tools #229

Merged
bema merged 33 commits from ref/simplify_xml_tools into master 2023-06-21 14:32:02 +02:00
28 changed files with 573 additions and 329 deletions

View File

@@ -8,6 +8,7 @@ server {
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1;
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}

View File

@@ -6,9 +6,9 @@ import SidebarComponent from '@components/sidebar/SidebarComponent.vue';
</script>
<template>
<div id="layout" class="flex bg-gradient-to-r from-white to-blue-200 dark:from-slate-800 dark:to-indigo-950">
<div id="layout" class="flex h-screen bg-gradient-to-r from-white to-sky-200 dark:from-slate-800 dark:to-indigo-950">
<SidebarComponent />
<div class="relative p-6 w-full m-4 bg-indigo-50 dark:bg-gray-700 rounded-2xl shadow-md">
<div class="relative p-6 w-full m-4 bg-blue-50 dark:bg-gray-700 rounded-2xl shadow-lg">
<RouterView></RouterView>
</div>
</div>

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<library>
<libraryName>City library</libraryName>
<libraryID>345123</libraryID>
<readerList>
<person>
<readerID>7321</readerID>
<name>Adam</name>
<surname>Choke</surname>
</person>
<person>
<readerID>5123</readerID>
<name>Lauren</name>
<surname>Wong</surname>
</person>
</readerList>
<bookList>
<book>
<bookID>6422</bookID>
<title>Harry Potter</title>
<readerID>7542</readerID>
</book>
<book>
<bookID>1234</bookID>
<title>Macbeth</title>
<readerID>5123</readerID>
</book>
<book>
<bookID>9556</bookID>
<title>Romeo and Juliet</title>
</book>
</bookList>
</library>

View File

@@ -1,7 +1,5 @@
declare namespace p="http://www.release11.com/person";
declare namespace b="http://www.release11.com/book";
declare namespace l="http://www.release11.com/library";
declare default element namespace "http://www.release11.com/schemas/Sample.xsd";
Review

Try to get rid of these "tibco" watermark

Try to get rid of these "tibco" watermark
declare namespace u = "http://www.release11.com/schemas/Sample.xsd";
for $x in //p:person
return string($x/p:name)
for $x in /u:root/u:UserList[@Id = 'a']/u:User
return string($x/u:Name)

View File

@@ -1,33 +1,62 @@
<?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>
<?xml version = "1.0" encoding = "UTF-8"?>
<u:root xmlns:u = "http://www.release11.com/schemas/Sample.xsd" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.tibco.com/schemas/Shemy4tools/Folder/Schema.xsd Schema4tools.xsd">
<u:UserList Id = "a">
<u:User Id = "1">
<u:Name>John</u:Name>
<u:Surname>Wick</u:Surname>
<u:DateOfDeath>2023-10-10</u:DateOfDeath>
</u:User>
<u:User Id = "2">
<u:Name>Martha</u:Name>
<u:Surname>Whane</u:Surname>
<u:DateOfDeath>1970-06-13</u:DateOfDeath>
</u:User>
<u:User Id = "3">
<u:Name>Bruce</u:Name>
<u:Surname>Lee</u:Surname>
<u:DateOfDeath>1985-01-24</u:DateOfDeath>
</u:User>
<u:User Id = "4">
<u:Name>John</u:Name>
<u:Surname>Rambo</u:Surname>
<u:DateOfDeath>2024-06-19</u:DateOfDeath>
</u:User>
<u:NameList>FirstList</u:NameList>
</u:UserList>
<u:UserList Id = "b">
<u:User Id = "1">
<u:Name>Jack</u:Name>
<u:Surname>Wicker</u:Surname>
<u:DateOfDeath>2023-10-10</u:DateOfDeath>
</u:User>
<u:NameList>SecondList</u:NameList>
</u:UserList>
<u:UserList Id = "c">
<u:User Id = "1">
<u:Name>New</u:Name>
<u:Surname>Folder</u:Surname>
<u:DateOfDeath>2023-11-10</u:DateOfDeath>
</u:User>
<u:User Id = "2">
<u:Name>Newer</u:Name>
<u:Surname>Folder</u:Surname>
<u:DateOfDeath>2023-11-11</u:DateOfDeath>
</u:User>
<u:User Id = "3">
<u:Name>Newest</u:Name>
<u:Surname>Folder</u:Surname>
<u:DateOfDeath>2023-11-12</u:DateOfDeath>
</u:User>
<u:User Id = "4">
<u:Name>New</u:Name>
<u:Surname>Folder2</u:Surname>
<u:DateOfDeath>2023-11-13</u:DateOfDeath>
</u:User>
<u:User Id = "5">
<u:Name>New</u:Name>
<u:Surname>Folder-Final</u:Surname>
<u:DateOfDeath>2023-11-14</u:DateOfDeath>
</u:User>
<u:NameList>ThirdList</u:NameList>
</u:UserList>
</u:root>

View File

@@ -1,42 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="">
<xsd:element name="library">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element minOccurs="0" name="libraryName" type="xsd:string" />
<xsd:element minOccurs="0" name="libraryID" type="xsd:int" />
<xsd:element minOccurs="0" name="readerList">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="person">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element minOccurs="0" name="readerID" type="xsd:int" />
<xsd:element minOccurs="0" name="name" type="xsd:normalizedString" />
<xsd:element minOccurs="0" name="surname" type="xsd:normalizedString" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="0" name="bookList">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="book">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element minOccurs="0" name="bookID" type="xsd:int" />
<xsd:element minOccurs="0" name="title" type="xsd:string" />
<xsd:element minOccurs="0" name="readerID" type="xsd:int" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:u="http://www.release11.com/schemas/Sample.xsd"
targetNamespace="http://www.release11.com/schemas/Sample.xsd"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="u:UserList" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="UserList">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element ref="u:User" maxOccurs="unbounded"/>
<xs:element ref="u:NameList"/>
</xs:sequence>
<xs:attribute name="Id" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:simpleType name="User">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:element name="User">
<xs:complexType>
<xs:sequence>
<xs:element ref="u:Name"/>
<xs:element ref="u:Surname"/>
<xs:element ref="u:DateOfDeath"/>
</xs:sequence>
<xs:attribute name="Id" type="xs:int" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Surname" type="xs:string"/>
<xs:element name="DateOfDeath" type="xs:date"/>
<xs:element name="NameList" type="xs:string"/>
</xs:schema>

View File

@@ -1,14 +1,17 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:b="http://www.release11.com/book" xmlns:p="http://www.release11.com/person"
xmlns:l="http://www.release11.com/library">
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:u = "http://www.release11.com/schemas/Sample.xsd"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Library>
<ReaderCount>
<xsl:value-of select="count(//p:person)" />
</ReaderCount>
<BookCount>
<xsl:value-of select="count(/l:library/l:bookList/b:book)" />
</BookCount>
</Library>
<UserLists>
<UserListCount>
<xsl:value-of select="count(/u:root/u:UserList)" />
</UserListCount>
<xsl:for-each select="/u:root/u:UserList">
<UserListStats>
<Name><xsl:value-of select="u:NameList" /></Name>
<UserCount><xsl:value-of select="count(u:User)" /></UserCount>
</UserListStats>
</xsl:for-each>
</UserLists>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,47 @@
<script setup lang="ts">
import sampleXML from "@/assets/sampleXml.xml?raw"
import sampleXSLT from "@/assets/sampleXslt.xml?raw"
import sampleXSD from "@/assets/sampleXsd.xml?raw"
import sampleXQuery from "@/assets/sampleXQuery.xquery?raw"
const props = defineProps(
{
stylizedName: {type: String, required: true}
Review

prettifiedName, or something else.
Name imo should be more descriptive.

prettifiedName, or something else. Name imo should be more descriptive.
}
)
const emit = defineEmits(['update:defaultData'])
function setDefault() {
const emitName = "update:defaultData";
switch (props.stylizedName.toLowerCase()) {
case "json":
emit(emitName, "{'message': 'Here we have to add some proper message', 'answer': 'Ya, definitely'}")
break;
case "xpath":
emit(emitName, "/u:root/u:UserList/u:User[../u:NameList = 'FirstList']")
break;
case "xsd":
emit(emitName, sampleXSD)
break;
case "xslt":
emit(emitName, sampleXSLT)
break;
case "xquery":
emit(emitName, sampleXQuery)
break;
default:
emit(emitName, sampleXML)
break;
}
}
</script>
<template>
<button class="tool-button" @click="setDefault()">Default {{ stylizedName }}</button>
</template>

View File

@@ -1,10 +0,0 @@
<script setup lang="ts">
</script>
<template>
<h1>Formatter</h1>
</template>
<style scoped></style>

View File

@@ -0,0 +1,54 @@
<script setup lang="ts">
const props = defineProps({
json: {type: String, required: true},
isMinimizer: {type: Boolean}
})
const emit = defineEmits(["update:result"])
function process() {
var request:Request = prepareRequest();
fetchRequest(request).then((data) => {
sendProcessedData(data);
})
}
function prepareRequest():Request {
var request = new Request(prepareURL(), {
body: prepareRequestBody(),
method: "POST"
});
return request;
}
function prepareURL(): string {
var mode = "formatting";
if (props.isMinimizer)
mode = "minimize";
return document.location.protocol + "//" + document.location.hostname + "/java/json/" + mode;
}
function prepareRequestBody():string {
var requestBody = props.json;
return requestBody;
}
async function fetchRequest(request: Request):Promise<JSON> {
var responseBody = await fetch(request)
.then(response => response.json())
.then((body) => body);
console.log(responseBody);
return responseBody;
}
function sendProcessedData(data: JSON) {
emit("update:result", data);
}
</script>
<template>
<button class="tool-button" @click="process()">{{ props.isMinimizer ? "Minimize" : "Format" }}</button>
</template>
<style scoped></style>

View File

@@ -0,0 +1,58 @@
<script setup lang="ts">
const props = defineProps({
xml: {type: String, required: true},
isMinimizer: {type: Boolean}
Review

isMinimizer boolean it's good option, when we have only two options, but in future when we'll need to add another option like for example "removeNamespaces" we need refactor larger piece of code. I suggest to make prop "formatType", with type String.

isMinimizer boolean it's good option, when we have only two options, but in future when we'll need to add another option like for example "removeNamespaces" we need refactor larger piece of code. I suggest to make prop "formatType", with type String.
})
const emit = defineEmits(["update:result"])
function process() {
var request:Request = prepareRequest();
fetchRequest(request).then((data) => {
sendProcessedData(data);
})
}
function prepareRequest():Request {
var request = new Request(prepareURL(), {
body: prepareRequestBody(),
method: "POST"
});
return request
}
function prepareURL(): string {
var mode = "prettify";
if (props.isMinimizer)
mode = "minimize";
return document.location.protocol + "//" + document.location.hostname + "/libxml/" + mode;
}
function prepareRequestBody():string {
var requestBody = JSON.stringify({
"data": props.xml,
"process": "N/A",
"processor": "libxml",
"version": "1.0"
});
return requestBody;
}
async function fetchRequest(request: Request):Promise<JSON> {
var responseBody = await fetch(request)
.then(response => response.json())
.then((body) => body);
return responseBody;
}
function sendProcessedData(data: JSON) {
emit("update:result", data);
}
</script>
<template>
<button class="tool-button" @click="process()">{{ props.isMinimizer ? "Minimize" : "Format" }}</button>
</template>
<style scoped></style>

View File

@@ -3,7 +3,16 @@
</script>
<template>
<h1 class="text-3xl underline">Landing</h1>
<div class="dark:text-slate-100">
<h1 class="text-3xl mb-4">Welcome to Release11 Tools</h1>
<h2 class="text-xl">Our toolset is split to three main categories:</h2>
<ol class="list-decimal ml-5">
<li><strong>XML</strong> - containing various tools that allow to validate and transform any XML</li>
<li><strong>Formatter</strong> - containing tools for formatting text files in various formats</li>
<li><strong>REST</strong> - consist of Mock that allows to create mocked REST endpoint</li>
</ol>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,15 @@
<script setup lang="ts">
</script>
<template>
<div class="flex flex-col gap-4 text-center font-thin text-slate-600 dark:text-slate-400 ">
<div class="flex flex-col">
<a href="mailto:bugs@release11.com">Found a bug?</a>
<a href="#" class="hidden">Privacy Policy</a>
</div>
<span>Copyright 2023 <br/> Release11</span>
</div>
</template>

View File

@@ -2,6 +2,7 @@
import { ref , onMounted} from 'vue'
import SidebarToolLinkComponent from './SidebarToolLinkComponent.vue';
import SidebarMenuElementComponent from './SidebarMenuElementComponent.vue';
import FooterComponent from './FooterComponent.vue';
import logoDark from '@assets/logo_biale.svg';
import logoWhite from '@assets/logo_czarne.svg';
@@ -24,11 +25,11 @@ onMounted( () => {
<template>
<aside class="relative flex-shrink-0 top-0 left-0 z-40 w-48 h-screen" >
<div class="h-full px-3 pt-2 pb-4 overflow-y-auto">
<div class="flex flex-col h-full px-3 pt-2 pb-4 overflow-y-auto">
<a href="https://release11.com/">
<img :src="logoR11" class="w-72 h-16 p-2 pt-0"/>
</a>
<div class="flex flex-col font-medium items-center">
<div class="flex basis-full flex-col font-medium items-center">
<sidebar-menu-element-component category-name="XML">
<SidebarToolLinkComponent path-to="/xml/xpath" element-content="XPath" />
<SidebarToolLinkComponent path-to="/xml/xquery" element-content="XQuery" />
@@ -37,9 +38,9 @@ onMounted( () => {
</sidebar-menu-element-component>
<sidebar-menu-element-component category-name="Formatter">
<SidebarToolLinkComponent path-to="/format/HTML" element-content="HTML Formatter" />
<SidebarToolLinkComponent path-to="/format/JSON" element-content="JSON Formatter" />
<SidebarToolLinkComponent path-to="/format/XML" element-content="XML Formatter" />
<SidebarToolLinkComponent path-to="/format/HTML" element-content="HTML" />
<SidebarToolLinkComponent path-to="/format/JSON" element-content="JSON" />
<SidebarToolLinkComponent path-to="/format/XML" element-content="XML" />
</sidebar-menu-element-component>
@@ -48,6 +49,7 @@ onMounted( () => {
</sidebar-menu-element-component>
</div>
<FooterComponent></FooterComponent>
</div>
</aside>
</template>

View File

@@ -17,7 +17,7 @@ const props = defineProps(
<template>
<div class="w-full mb-4 p-2 rounded-xl shadow-md bg-gradient-to-r from-blue-400 to-blue-200 dark:from-sky-700 dark:to-sky-900">
<div class="w-full mb-4 p-2 rounded-xl shadow-lg bg-gradient-to-r from-blue-400 to-blue-300 dark:from-sky-700 dark:to-sky-900">
<button @click="switchHiddenElement()" type="button" :class="[isActive ? 'rounded-lg' : 'rounded-lg']" class="w-full p-2 text-lg font-bold text-gray-900 transition duration-75 hover:bg-blue-100 dark:text-gray-100 dark:hover:bg-slate-600">
<span class="flex-1 whitespace-nowrap">{{props.categoryName}}</span>
</button>

View File

@@ -1,47 +1,49 @@
<script setup lang="ts">
import xmlInputFieldToolbarComponent from '@/components/xml/XmlInputFieldToolbarComponent.vue';
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue';
import XMLButtonFormatterComponent from '@components/formatter/XMLButtonFormatterComponent.vue'
import { ref } from 'vue';
const xml = ref('')
const query = ref('')
const data = ref('')
const props = defineProps(
{
prettyName: {type: String, required: true},
xmlData: {type: String},
stylizedName: {type: String, required: true},
data: {type: String},
}
)
const emit = defineEmits(['update:xml', 'update:transform'])
const emit = defineEmits(['update'])
function sendXml() {
emit('update:xml', xml.value)
function sendValue() {
emit('update', data.value)
}
function sendTransform() {
emit('update:transform', query.value)
function updateData(newData: string) {
data.value = newData;
sendValue();
}
function setToDefaultXML(data: string) {
xml.value = data;
sendXml();
function clear() {
updateData('');
}
function setToDefaultQuery(data: string) {
query.value = data;
sendTransform();
function canBeFormatted() {
return props.stylizedName.toLowerCase() == 'xml' ||
props.stylizedName.toLowerCase() == 'xsd' ||
props.stylizedName.toLowerCase() == 'xslt';
}
</script>
<template>
<div class="flex flex-col w-full lg:w-1/2 h-full items-center gap-4">
<div class="flex flex-col w-full h-1/2">
<xmlInputFieldToolbarComponent prettyName="XML" @update:defaultData="(data) => setToDefaultXML(data)"></xmlInputFieldToolbarComponent>
<textarea id="xmlField" v-model="xml" @input="sendXml()" class="w-full h-full resize-none dark:text-slate-100 dark:bg-gray-600 border border-slate-400 p-2 rounded-md"></textarea>
</div>
<div class="flex flex-col w-full h-1/2">
<xmlInputFieldToolbarComponent :prettyName="$props.prettyName" @update:defaultData="(data) => setToDefaultQuery(data)"></xmlInputFieldToolbarComponent>
<textarea id="transformField" v-model="query" @input="sendTransform()" class="w-full h-full resize-none dark:text-slate-100 dark:bg-gray-600 border border-slate-400 p-2 rounded-md"></textarea>
<div class="flex flex-col w-full h-1/2">
<div class="flex place-content-between w-full pr-2 items-center m-2">
<span class="dark:text-white">{{ stylizedName }}</span>
<div class="flex space-x-2">
<InsertTemplateComponent :stylized-name="props.stylizedName" @update:default-data="(data: string) => updateData(data)"></InsertTemplateComponent>
<XMLButtonFormatterComponent v-if="canBeFormatted()" :xml="data" @update:result="(data:any) => updateData(data.result)"></XMLButtonFormatterComponent>
<button class="tool-button" @click="clear">Clear</button>
</div>
</div>
<textarea id="xmlField" v-model="data" @input="sendValue()" class="text-field"></textarea>
</div>
</template>

View File

@@ -1,10 +1,6 @@
<script setup lang="ts">
import sampleXML from "@/assets/sampleXml.xml?raw"
import sampleXSLT from "@/assets/sampleXslt.xml?raw"
import sampleXSD from "@/assets/sampleXsd.xml?raw"
import sampleXQuery from "@/assets/sampleXQuery.xquery?raw"
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue'
const props = defineProps(
{
@@ -14,37 +10,13 @@ const props = defineProps(
const emit = defineEmits(['update:defaultData'])
function setDefault() {
function setDefault(data: string) {
const emitName = "update:defaultData";
switch (props.prettyName.toLowerCase()) {
case "xpath":
emit(emitName, "string(/l:library/l:libraryName)")
break;
case "xsd":
emit(emitName, sampleXSD)
break;
case "xslt":
emit(emitName, sampleXSLT)
break;
case "xquery":
emit(emitName, sampleXQuery)
break;
default:
emit(emitName, sampleXML)
break;
}
emit(emitName, data)
}
</script>
<template>
<div class="flex place-content-between w-full pr-2 items-center m-2">
<span class="dark:text-white">{{ prettyName }}</span>
<div class="flex space-x-2">
<button class="tool-button" @click="setDefault()">Insert default {{ prettyName }}</button>
</div>
</div>
</template>

View File

@@ -1,6 +1,5 @@
<script setup lang="ts">
import xmlOutputFieldToolbarComponent from '@/components/xml/XmlOutputFieldToolbarComponent.vue';
import { ref } from 'vue';
import { onMounted, ref } from 'vue';
const props = defineProps(
@@ -13,18 +12,132 @@ const props = defineProps(
const result = ref('');
function parseResult(data: any) {
var enginesForCurrentTool = ref(["saxon", "xalan", "libxml"]);
const allVersions = ["1.0", "2.0", "3.0", "3.1"];
var versionsForCurrentEngine = ref([""]);
const engine = ref('');
const version = ref('');
onMounted(() => {
changeAvailableEngines();
changeAvailableVersions();
})
function changeAvailableEngines() {
if (props.tool == "xsd") {
enginesForCurrentTool.value = ["xalan", "libxml"]
}
else if (props.tool == "xquery") {
enginesForCurrentTool.value = ["saxon"]
}
selectDefaultEngine();
}
function changeAvailableVersions() {
if (props.tool == "xquery")
versionsForCurrentEngine.value = ["3.1"];
else if (props.tool == "xslt")
changeAvailableVersionsOfXSLT();
else if (props.tool == "xsd")
versionsForCurrentEngine.value = ["N/A"];
else if (props.tool == "xpath")
changeAvailableVersionsOfXPath();
selectDefaultVersion();
}
function changeAvailableVersionsOfXSLT() {
if(engine.value == "saxon")
versionsForCurrentEngine.value = ["3.0"];
else
versionsForCurrentEngine.value = ["1.0"];
}
function changeAvailableVersionsOfXPath() {
if(engine.value == "xalan" || engine.value == "libxml")
versionsForCurrentEngine.value = ["1.0"];
else if (engine.value == "saxon")
versionsForCurrentEngine.value = allVersions;
}
function selectDefaultEngine() {
engine.value = enginesForCurrentTool.value[0];
}
function selectDefaultVersion() {
const lastVersion = versionsForCurrentEngine.value.length - 1
version.value = versionsForCurrentEngine.value[lastVersion];
}
function process() {
var request:Request = prepareRequest();
fetchRequest(request).then((data) => {
updateOutputField(data);
})
}
function prepareRequest():Request {
var request = new Request(prepareURL(), {
body: prepareRequestBody(),
method: "POST"
});
return request
}
function prepareURL(): string {
const engineEndpoint = engine.value == "libxml" ? "libxml" : "java";
return document.location.protocol + "//" + document.location.hostname + "/" + engineEndpoint + "/" + props.tool;
}
function prepareRequestBody():string {
var requestBody = JSON.stringify({
"data": props.xml,
"process": props.query,
"processor": engine.value,
"version": version.value
});
return requestBody;
}
async function fetchRequest(request: Request):Promise<JSON> {
var responseBody = await fetch(request)
.then(response => response.json())
.then((body) => body);
return responseBody;
}
function updateOutputField(data: any) {
result.value = data.result;
}
function clear() {
result.value = "";
}
</script>
<template>
<div class="flex flex-col w-full lg:w-1/2 h-full items-center">
<xmlOutputFieldToolbarComponent :xml="$props.xml" :query="$props.query" :tool="$props.tool" @update:result="(data) => parseResult(data)"></xmlOutputFieldToolbarComponent>
<div class="w-full h-full p-2 overflow-scroll border border-slate-400 rounded-md text-left bg-white dark:text-slate-100 dark:bg-gray-600">
<pre class="break-words"><code>{{ result }}</code></pre>
<div class="flex flex-col w-full lg:w-1/2 h-1/2 lg:h-full items-center">
<div class="flex place-content-between w-full items-center m-2">
<span class="dark:text-white">Result:</span>
<div class="flex space-x-2">
<select v-model="engine" name="engine" @change="changeAvailableVersions()" class="px-3 rounded-full border border-slate-400 bg-white dark:text-slate-100 dark:bg-gray-600">
<option v-for="engine in enginesForCurrentTool" :value="engine">{{ engine }}</option>
</select>
<select v-model="version" name="version" class="px-3 rounded-full border border-slate-400 bg-white dark:text-slate-100 dark:bg-gray-600">
<option v-for="version in versionsForCurrentEngine" :value="version">{{ version }}</option>
</select>
<button class="tool-button" @click="clear">Clear</button>
<button class="tool-button" @click="process">Process</button>
</div>
</div>
<div class="text-field overflow-scroll h-full w-full">
<pre class="whitespace-pre-wrap"><code>{{ result }}</code></pre>
</div>
</div>
</template>
</template>

View File

@@ -1,112 +0,0 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
var engines = ["saxon", "xalan", "libxml"];
var versions = ["1.0", "2.0", "3.0", "3.1"];
const props = defineProps(
{
tool: {type: String, required: true},
xml: {type: String},
query: {type: String},
}
)
const emit = defineEmits(['update:result'])
const engine = ref('');
const version = ref('');
const isSaxonHidden = ref(false);
const isXalanHidden = ref(false);
const isLibXMLHidden = ref(false);
onMounted(() => {
selectAvailableEngines();
selectAvailableVersions();
selectDefaults();
})
function selectAvailableEngines() {
if (props.tool == "xsd") {
engines = ["xalan", "libxml"]
}
else if (props.tool == "xquery") {
engines = ["saxon"]
}
}
function selectAvailableVersions() {
if (props.tool == "xquery")
versions = ["3.1"];
else if (props.tool == "xsd")
versions = ["N/A"];
}
function selectDefaults() {
version.value = versions[versions.length - 1];
engine.value = engines[0];
}
function process() {
var request:Request = prepareRequest();
fetchRequest(request).then((data) => {
sendProcessedData(data);
})
}
function prepareRequest():Request {
var request = new Request(prepareURL(), {
body: prepareRequestBody(),
method: "POST"
});
return request
}
function prepareURL(): string {
const engineEndpoint = engine.value == "libxml" ? "libxml" : "java";
return document.location.protocol + "//" + document.location.hostname + "/" + engineEndpoint + "/" + props.tool;
}
function prepareRequestBody():string {
var requestBody = JSON.stringify({
"data": props.xml,
"process": props.query,
"processor": engine.value,
"version": version.value
});
return requestBody;
}
async function fetchRequest(request: Request):Promise<JSON> {
var responseBody = await fetch(request)
.then(response => response.json())
.then((body) => body);
return responseBody;
}
function sendProcessedData(data: JSON) {
emit("update:result", data);
}
</script>
<template>
<div class="flex place-content-between w-full items-center m-2">
<span class="dark:text-white">Result:</span>
<div class="flex space-x-2">
<select v-model="engine" name="engine" class="px-3 rounded-full border border-slate-400 bg-white dark:text-slate-100 dark:bg-gray-600">
<option v-for="engine in engines" :value="engine">{{ engine }}</option>
</select>
<select v-model="version" name="version" class="px-3 rounded-full border border-slate-400 bg-white dark:text-slate-100 dark:bg-gray-600">
<option v-for="version in versions" :value="version">{{ version }}</option>
</select>
<button class="tool-button">Clear</button>
<button class="tool-button" @click="process">Process</button>
</div>
</div>
</template>

View File

@@ -3,6 +3,9 @@ import { createRouter, createWebHistory } from 'vue-router'
const landingPage = import("@views/LandingView.vue")
const restMock = import("@views/RestMockView.vue")
const jsonFormatter = import("@views/JsonFormatterView.vue")
const xmlFormatter = import("@views/XmlFormatterView.vue")
const xsltTool = import("@views/XSLTView.vue")
const xsdTool = import("@views/XSDView.vue")
const xpathTool = import("@views/XPathView.vue")
@@ -14,6 +17,16 @@ const routes = [
name: 'landing',
component: () => landingPage
},
{
path: '/format/xml',
name: 'xmlFormatter',
component: () => xmlFormatter
},
{
path: '/format/json',
name: 'jsonFormatter',
component: () => jsonFormatter
},
{
path: '/xml/xpath',
name: 'xpath',

View File

@@ -3,5 +3,9 @@
@tailwind utilities;
.tool-button {
@apply py-1 px-4 rounded-full bg-gradient-to-r from-blue-300 to-sky-200 dark:text-white dark:from-sky-600 dark:to-sky-800 hover:bg-blue-400
@apply py-1 px-4 rounded-full w-fit bg-gradient-to-r from-blue-400 to-blue-300 dark:text-white dark:from-sky-600 dark:to-sky-800 hover:bg-blue-400
}
.text-field {
@apply w-full h-full resize-none font-mono bg-white dark:text-slate-100 dark:bg-gray-600 border border-slate-400 p-2 rounded-md
}

View File

@@ -0,0 +1,36 @@
<script setup lang="ts">
import JsonButtonFormatterComponent from '@/components/formatter/JsonButtonFormatterComponent.vue';
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue';
import { ref } from 'vue';
const json = ref('');
function setTextFieldValue(data: string) {
json.value = data
}
function format(formattedXml: any) {
json.value = formattedXml.data;
}
function clear() {
json.value = '';
}
</script>
<template>
<div id="layout" class="flex flex-col w-full h-full gap-4">
<div id="toolbar" class= "flex flex-col gap-4 items-center lg:flex-row place-content-between">
<span class="dark:text-slate-100">JSON Formatter</span>
<div class="flex flex-wrap gap-2 justify-center">
<InsertTemplateComponent stylized-name="JSON" @update:defaultData="(data: string) => setTextFieldValue(data)"></InsertTemplateComponent>
<button class="tool-button" @click="clear()">Clear</button>
<JsonButtonFormatterComponent isMinimizer :json="json" @update:result="(data: any) => format(data)"></JsonButtonFormatterComponent>
<JsonButtonFormatterComponent :json="json" @update:result="(data: any) => format(data)"></JsonButtonFormatterComponent>
</div>
</div>
<textarea name="data" id="data" :value="json" class="text-field"></textarea>
</div>
</template>

View File

@@ -11,8 +11,10 @@ const query = ref('');
<template>
<div id="layout" class="flex flex-col lg:flex-row w-full h-full gap-4">
<xmlInputFieldComponent prettyName="XPath" @update:xml="(data) => {xml = data}" @update:transform="(data) => {query = data}"></xmlInputFieldComponent>
<div class="flex flex-col w-full lg:w-1/2 h-full items-center gap-4">
<xmlInputFieldComponent stylized-name="XML" :data="xml" @update="(data) => {xml = data}"></xmlInputFieldComponent>
<xmlInputFieldComponent stylized-name="XPath" :data="query" @update="(data) => {query = data}"></xmlInputFieldComponent>
</div>
<xmlOutputFieldComponent tool="xpath" :xml="xml" :query="query"></xmlOutputFieldComponent>
</div>
</template>

View File

@@ -11,8 +11,10 @@ const query = ref('');
<template>
<div id="layout" class="flex flex-col lg:flex-row w-full h-full gap-4">
<xmlInputFieldComponent prettyName="XQuery" @update:xml="(data) => {xml = data}" @update:transform="(data) => {query = data}"></xmlInputFieldComponent>
<div class="flex flex-col w-full lg:w-1/2 h-full items-center gap-4">
<xmlInputFieldComponent stylized-name="XML" @update="(data) => {xml = data}"></xmlInputFieldComponent>
<xmlInputFieldComponent stylized-name="XQuery" @update="(data) => {query = data}"></xmlInputFieldComponent>
</div>
<xmlOutputFieldComponent tool="xquery" :xml="xml" :query="query"></xmlOutputFieldComponent>
</div>
</template>

View File

@@ -11,8 +11,10 @@ const query = ref('');
<template>
<div id="layout" class="flex flex-col lg:flex-row w-full h-full gap-4">
<xmlInputFieldComponent prettyName="XSD" @update:xml="(data) => {xml = data}" @update:transform="(data) => {query = data}"></xmlInputFieldComponent>
<div class="flex flex-col w-full lg:w-1/2 h-full items-center gap-4">
<xmlInputFieldComponent stylized-name="XML" @update="(data) => {xml = data}"></xmlInputFieldComponent>
<xmlInputFieldComponent stylized-name="XSD" @update="(data) => {query = data}"></xmlInputFieldComponent>
</div>
<xmlOutputFieldComponent tool="xsd" :xml="xml" :query="query"></xmlOutputFieldComponent>
</div>
</template>

View File

@@ -11,8 +11,10 @@ const query = ref('');
<template>
<div id="layout" class="flex flex-col lg:flex-row w-full h-full gap-4">
<xmlInputFieldComponent prettyName="XSLT" @update:xml="(data) => {xml = data}" @update:transform="(data) => {query = data}"></xmlInputFieldComponent>
<div class="flex flex-col w-full lg:w-1/2 h-full items-center gap-4">
<xmlInputFieldComponent stylized-name="XML" @update="(data) => {xml = data}"></xmlInputFieldComponent>
<xmlInputFieldComponent stylized-name="XSLT" @update="(data) => {query = data}"></xmlInputFieldComponent>
</div>
<xmlOutputFieldComponent tool="xslt" :xml="xml" :query="query"></xmlOutputFieldComponent>
</div>
</template>

View File

@@ -0,0 +1,36 @@
<script setup lang="ts">
import XMLButtonFormatterComponent from '@/components/formatter/XMLButtonFormatterComponent.vue';
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue';
import { ref } from 'vue';
const xml = ref('');
function setTextFieldValue(data: string) {
xml.value = data
}
function format(formattedXml: any) {
xml.value = formattedXml.result;
}
function clear() {
xml.value = '';
}
</script>
<template>
<div id="layout" class="flex flex-col w-full h-full gap-4">
<div id="toolbar" class= "flex flex-col gap-4 items-center lg:flex-row place-content-between">
<span class="dark:text-slate-100">XML Formatter</span>
<div class="flex flex-wrap gap-2 justify-center">
<InsertTemplateComponent stylized-name="XML" @update:defaultData="(data: string) => setTextFieldValue(data)"></InsertTemplateComponent>
<button class="tool-button" @click="clear()">Clear</button>
<XMLButtonFormatterComponent is-minimizer :xml="xml" @update:result="(data: any) => format(data)"></XMLButtonFormatterComponent>
<XMLButtonFormatterComponent :xml="xml" @update:result="(data: any) => format(data)"></XMLButtonFormatterComponent>
</div>
</div>
<textarea name="data" id="data" :value="xml" class="text-field"></textarea>
</div>
</template>