{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["tabs","tab"]},"type":"markdown"},"seo":{"title":"Validating Templates","description":"Accelerate E&P application development and protect your innovation by consuming our Data and Domain APIs / Platform APIs.","lang":"en-US","meta":[{"name":"robots","content":"noindex"}],"llmstxt":{"hide":true,"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"validating-templates","__idx":0},"children":["Validating Templates"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Validating templates is based on JSON Schema. JSON Schema is a vocabulary that allows annotation and validation of JSON documents. In this tutorial, find some tools and references for schema validation. Information is provided about server-side and client-side schema validation tools and how to use them. As an example, the GeoToolkit schemas and objects are used."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"nodejs-validation","__idx":1},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/DataAndTemplates/ValidatingTemplates/validatingTemplates#nodejs"},"children":["#"]}," NodeJS Validation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["One of the environments which has tools to validate schema is a NodeJS server.npm repository which has multiple JSON schema validators, but this tutorial will focus on ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://www.npmjs.com/package/ajv"},"children":["AJV"]}," - a lightweight, fast, and easy to use schema validator compatible with the draft-07 standard. Download and install the npm module to use it:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["npm install ajv"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Usage of the library is straightforward. For example, to validate a serialized ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["geotoolkit/attributes/TextStyle"]},", the steps are as follows:"]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"div","attributes":{"label":"css","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"css","header":{"controls":{"copy":{}}},"source":"\n.cg-tooltip-holder {\n  position: relative;\n}\n\n.cg-tooltip {\n  position: absolute;\n  display: block;\n  padding: 2px 12px 3px 7px;\n  overflow: visible !important;\n  font-family: Roboto, Helvetica, Arial, sans-serif;\n  font-size: 13px;\n  background: white !important;\n  opacity: 0.9;\n  color: #333333;\n  border: solid 1px gray;\n  border-radius: 5px;\n  text-align: left;\n  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n  border-radius: 5px;\n  margin: 0 !important;\n  z-index: 10000;\n  max-width: 400px;\n  text-wrap: normal !important;\n  white-space: normal !important;\n}\n/* Default setting for tooltip */\n.cg-tooltip-container {\n  position: absolute;\n  display: block;\n  overflow: visible !important;\n  font-family: Roboto, Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  padding: 3px 7px;\n  background: #f7f7f7;\n  color: #333333;\n  border: 1px solid #938e8e;\n  opacity: 0.8;\n  text-align: left;\n  box-shadow: 3px 3px 10px #888;\n  margin: 0 !important;\n  z-index: 10000;\n  max-width: 400px;\n  text-wrap: normal !important;\n  white-space: normal !important;\n  user-select: none;\n}\n@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {\n  .cg-tooltip-container {\n    border-radius: 0;\n  }\n}\n/* Default left arrow for tooltip */\n.cg-tooltip-arrow-left::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 0;\n  top: 50%;\n  border: 5px solid transparent;\n  border-left: 0;\n  border-right: 5px solid  #938e8e;\n  transform: translate(calc(-100%), -50%);\n}\n.cg-tooltip-arrow-left::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 0;\n  top: 50%;\n  border: 4px solid transparent;\n  border-left: 0;\n  border-right: 4px solid #f7f7f7;\n  transform: translate(calc(-100%), -50%);\n}\n/* Default top arrow for tooltip */\n.cg-tooltip-arrow-top::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  top: 0;\n  border: 5px solid transparent;\n  border-top: 0;\n  border-bottom: 5px solid #938e8e;\n  transform: translate(-50%, -100%);\n}\n.cg-tooltip-arrow-top::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  top: 0;\n  border: 4px solid transparent;\n  border-top: 0;\n  border-bottom: 4px solid #f7f7f7;\n  transform: translate(-50%, -100%);\n}\n/* Default right arrow for tooltip */\n.cg-tooltip-arrow-right::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  right: 0;\n  top: 50%;\n  border: 5px solid transparent;\n  border-right: 0;\n  border-left: 5px solid #938e8e;\n  transform: translate(100%, -50%);\n}\n.cg-tooltip-arrow-right::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  right: 0;\n  top: 50%;\n  border: 4px solid transparent;\n  border-right: 0;\n  border-left: 4px solid #f7f7f7;\n  transform: translate(100%, -50%);\n}\n/* Default bottom arrow for tooltip */\n.cg-tooltip-arrow-bottom::before {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  bottom: 0px;\n  border: 5px solid transparent;\n  border-bottom: 0;\n  border-top: 5px solid #938e8e;\n  transform: translate(-50%, 100%);\n  z-index: 10000;\n}\n.cg-tooltip-arrow-bottom::after {\n  content: '';\n  position: absolute;\n  display: block;\n  width: 0px;\n  left: 50%;\n  bottom: 0;\n  border: 4px solid transparent;\n  border-bottom: 0;\n  border-top: 4px solid #f7f7f7;\n  transform: translate(-50%, 100%);\n  z-index: 10000;\n}\n/* Tooltip item name */\n/* Tooltip item value */\n/* .cg-tooltip-item-value */\n/* Tooltip item value */\n.cg-tooltip-item-unit {\n  text-transform: none;\n}\n\n.cg-tooltip-item-name {\n    text-transform: capitalize;\n    white-space: nowrap;\n    vertical-align: middle;\n    font-size: 13px;\n}\n.cg-tooltip-row {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  white-space: pre-wrap;\n  font-size: 12px;\n  line-height: 100%;\n  margin: 1px 0;\n}\n.cg-tooltip-title {\n  font-size: 13px;\n  height: 14px;\n  text-transform: capitalize;\n}\n.cg-tooltip-title .cg-tooltip-symbol {\n  margin-right: 0 !important;\n}\n.cg-tooltip-title-name {\n  vertical-align: middle;\n}\n.cg-tooltip-row + .cg-tooltip-row {\n  margin-top: 4px;\n}\n.cg-tooltip-row.cg-tooltip-title + .cg-tooltip-row {\n  margin-top: 5px;\n}\n.cg-tooltip-item-value + .cg-tooltip-item-unit {\n    margin-left: 1px;\n}\n/* Tooltip symbol */\n.cg-tooltip-symbol-cell {\n  display: inline-flex;\n  min-width: 13px; /* 10px size + 3px margin */\n}\n.cg-tooltip-symbol {\n  margin-right: 3px;\n  background-color: transparent;\n  display: block;\n}\n.cg-tooltip-symbol > img {\n  display: block;\n}\n.cg-tooltip-list-cell {\n  display: inline-flex;\n}\n.cg-tooltip-list-symbol {\n  display: block;\n  margin-right: 3px;\n  width: 6px;\n  height: 6px;\n  vertical-align: middle;\n  border-radius: 50%;\n  border: 1px solid rgba(0,0,0,.4);\n}\n.cg-tooltip-symbol-legacy {\n  border-radius: 4px;\n  margin-right: 5px;\n  height: 8px;\n  width: 8px;\n  display: inline-block;\n}\n.cg-tooltip-title-legacy {\n  font-weight: 900;\n}\n\n/* Tooltip symbol circle */\n.cg-tooltip-symbol.circle {\n  height: 10px;\n  width: 10px;\n  display: inline-block;\n  border-radius: 50%;\n  border: 1px solid rgba(0,0,0,.4);\n}\n/* Tooltip symbol line */\n.cg-tooltip-symbol.line {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    transform: scale(1.2, 0.2);\n}\n/* Tooltip symbol diamond */\n.cg-tooltip-symbol.diamond {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    transform: rotate(45deg);\n    border-radius: 0px;\n}\n/* Tooltip symbol square */\n.cg-tooltip-symbol.square {\n    height: 10px;\n    width: 10px;\n    display: inline-block;\n    border-radius: 0px;\n    border: 1px solid rgba(0,0,0,.4);\n}\n\n","lang":"css"},"children":[]}]},{"$$mdtype":"Tag","name":"div","attributes":{"label":"main","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ts","header":{"controls":{"copy":{}}},"source":"import '@int/geotoolkit/src/geotoolkit/environment.js';\n// import AJV from 'ajv';\nimport MyAJV from '/src/code/WellLog/DataAndTemplates/ValidatingTemplates/node/myajv.js';\nimport fs from '/empty.js';\nimport __vite__cjsImport3_url from \"/node_modules/.vite/deps/url.js?v=c623d97a\"; const fileURLToPath = __vite__cjsImport3_url[\"fileURLToPath\"];\nimport __vite__cjsImport4_path from \"/node_modules/.vite/deps/path.js?v=c623d97a\"; const path = __vite__cjsImport4_path.__esModule ? __vite__cjsImport4_path.default : __vite__cjsImport4_path;\nconst {dirname} = path;\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst ajv = new MyAJV();\nconst templatePath = path.resolve(__dirname, '../templates/template.json');\n\nfs.readFile(templatePath, (err, data) => {\n    if (err) {\n        throw new Error(err);\n    }\n    global.console.log('Template loaded');\n    const template = JSON.parse(data);\n    const schema = ajv.getSchema('/geotoolkit.attributes.TextStyle');\n    const result = ajv.validateSchema(schema, template);\n    if (result) {\n        const {validateResult, errors} = result;\n        global.console.log(`Compile result: ${validateResult ? 'success' : 'error'} with ${errors.length} error(s)`);\n        errors.forEach((err) => {\n            global.console.log(`- ${err.dataPath}:\\t${err.message}`);\n        });\n    } else {\n        global.console.log('Error on validation');\n    }\n});\n\ncreateScene();\n\n","lang":"ts"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"client-side-validation","__idx":2},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#/WellLog/DataAndTemplates/ValidatingTemplates/validatingTemplates#client"},"children":["#"]}," Client Side Validation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Schemas can also be validated inside an application on the browser side. This method is more costly because it is necessary to load all schemas to the client, as well as the objects to validate, however, this approach is beneficial because it allows dynamic validation and detachment from any server."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["​"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Select schema"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["​"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["​"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Select template"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["​"]}]},"headings":[{"value":"Validating Templates","id":"validating-templates","depth":1},{"value":"NodeJS Validation","id":"nodejs-validation","depth":3},{"value":"Client Side Validation","id":"client-side-validation","depth":3}],"frontmatter":{"title":"Validating Templates","seo":{"title":"Validating Templates"}},"lastModified":"2026-02-11T19:54:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/solutions/geotoolkit/tutorials/well-log/data-and-templates/validating-templates","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}