Skip to content

Commit 23214dc

Browse files
committed
feat(new tool): XPath tester
Fix CorentinTh#672
1 parent 318fb6e commit 23214dc

File tree

6 files changed

+105
-14
lines changed

6 files changed

+105
-14
lines changed

components.d.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,22 +129,15 @@ declare module '@vue/runtime-core' {
129129
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
130130
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
131131
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
132-
NCode: typeof import('naive-ui')['NCode']
133132
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
134133
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
135134
NEllipsis: typeof import('naive-ui')['NEllipsis']
136-
NForm: typeof import('naive-ui')['NForm']
137-
NFormItem: typeof import('naive-ui')['NFormItem']
138135
NH1: typeof import('naive-ui')['NH1']
139136
NH3: typeof import('naive-ui')['NH3']
140137
NIcon: typeof import('naive-ui')['NIcon']
141-
NInputNumber: typeof import('naive-ui')['NInputNumber']
142138
NLayout: typeof import('naive-ui')['NLayout']
143139
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
144140
NMenu: typeof import('naive-ui')['NMenu']
145-
NScrollbar: typeof import('naive-ui')['NScrollbar']
146-
NSlider: typeof import('naive-ui')['NSlider']
147-
NSwitch: typeof import('naive-ui')['NSwitch']
148141
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
149142
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
150143
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
@@ -187,6 +180,7 @@ declare module '@vue/runtime-core' {
187180
WifiQrCodeGenerator: typeof import('./src/tools/wifi-qr-code-generator/wifi-qr-code-generator.vue')['default']
188181
XmlFormatter: typeof import('./src/tools/xml-formatter/xml-formatter.vue')['default']
189182
XmlToJson: typeof import('./src/tools/xml-to-json/xml-to-json.vue')['default']
183+
XpathTester: typeof import('./src/tools/xpath-tester/xpath-tester.vue')['default']
190184
YamlToJson: typeof import('./src/tools/yaml-to-json-converter/yaml-to-json.vue')['default']
191185
YamlToToml: typeof import('./src/tools/yaml-to-toml/yaml-to-toml.vue')['default']
192186
YamlViewer: typeof import('./src/tools/yaml-viewer/yaml-viewer.vue')['default']

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"@vueuse/core": "^10.3.0",
4848
"@vueuse/head": "^1.0.0",
4949
"@vueuse/router": "^10.0.0",
50+
"@xmldom/xmldom": "^0.8.10",
5051
"bcryptjs": "^2.4.3",
5152
"change-case": "^4.1.2",
5253
"colord": "^2.9.3",
@@ -94,6 +95,7 @@
9495
"vue-tsc": "^1.8.1",
9596
"xml-formatter": "^3.3.2",
9697
"xml-js": "^1.6.11",
98+
"xpath": "^0.0.34",
9799
"yaml": "^2.2.1"
98100
},
99101
"devDependencies": {

pnpm-lock.yaml

Lines changed: 23 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { tool as base64FileConverter } from './base64-file-converter';
22
import { tool as base64StringConverter } from './base64-string-converter';
33
import { tool as basicAuthGenerator } from './basic-auth-generator';
44
import { tool as emailNormalizer } from './email-normalizer';
5+
import { tool as xpathTester } from './xpath-tester';
56

67
import { tool as asciiTextDrawer } from './ascii-text-drawer';
78

@@ -154,6 +155,7 @@ export const toolsByCategory: ToolCategory[] = [
154155
xmlFormatter,
155156
yamlViewer,
156157
emailNormalizer,
158+
xpathTester,
157159
],
158160
},
159161
{

src/tools/xpath-tester/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Brackets } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'XPath Tester',
6+
path: '/xpath-tester',
7+
description: 'Test XPath expression against XML content',
8+
keywords: ['xpath', 'xml', 'tester'],
9+
component: () => import('./xpath-tester.vue'),
10+
icon: Brackets,
11+
createdAt: new Date('2024-08-15'),
12+
});
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<script setup lang="ts">
2+
import XPathEngine from 'xpath';
3+
import { DOMParser } from '@xmldom/xmldom';
4+
import { useValidation } from '@/composable/validation';
5+
6+
const xpath = ref('//title');
7+
const xml = ref('<book><title>Harry Potter</title></book>');
8+
9+
const selectedNodes = computed(() => {
10+
try {
11+
const doc = new DOMParser().parseFromString(xml.value, 'text/xml');
12+
return XPathEngine.select(xpath.value, doc);
13+
}
14+
catch (e: any) {
15+
return e.toString();
16+
}
17+
});
18+
19+
const xmlValidation = useValidation({
20+
source: xml,
21+
rules: [
22+
{
23+
validator: (v) => {
24+
new DOMParser().parseFromString(v, 'text/xml');
25+
return true;
26+
},
27+
message: 'Provided XML is not valid.',
28+
},
29+
],
30+
});
31+
</script>
32+
33+
<template>
34+
<div style="max-width: 600px;">
35+
<c-card title="Input" mb-2>
36+
<c-input-text
37+
v-model:value="xpath"
38+
label="XPath Expression"
39+
placeholder="Put your XPath expression here..."
40+
mb-2
41+
/>
42+
43+
<c-input-text
44+
v-model:value="xml"
45+
label="XML"
46+
multiline
47+
placeholder="Put your XML here..."
48+
rows="5"
49+
:validation="xmlValidation"
50+
mb-2
51+
/>
52+
</c-card>
53+
54+
<c-card title="Result(s)">
55+
<ul v-if="selectedNodes?.length > 0">
56+
<li v-for="(node, index) in selectedNodes" :key="index">
57+
{{ node }}
58+
</li>
59+
</ul>
60+
<c-alert v-if="!selectedNodes?.length">
61+
XPath expression selected nothing
62+
</c-alert>
63+
</c-card>
64+
</div>
65+
</template>

0 commit comments

Comments
 (0)