-
Notifications
You must be signed in to change notification settings - Fork 6
Description
I have an issue and I don't exactly know from where ir comes, but I can reproduce it.
My stack is node js 20.17.0, express.js and the issues happens on mac and linux as well.
Wherenver the process restarts the first validation fails finding the proper paths to the imports from the schema, the following calls to the validation works. I had to implement a retry logic to bypass the issue for whenever i push an update to production.
It is either me that misuses the library and the imports, or there is indeed something under the hood on how it initializes or waits for stuff.
const path = require("path");
const fs = require("fs").promises;
async function retry(fn, retries = 3, delay = 1000) {
for (let i = 0; i < retries; i++) {
try {
// Try executing the function
return await fn();
} catch (error) {
if (i === retries - 1) {
// If it's the last attempt, rethrow the error
throw error;
}
// Wait for the specified delay before retrying
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}
async function validateXml(xmlString) {
return await retry(
async () => {
try {
const { XmlDocument, XsdValidator } = await import("libxml2-wasm");
const { xmlRegisterFsInputProviders } = await import("libxml2-wasm/lib/nodejs.mjs");
xmlRegisterFsInputProviders();
const schemaDir = path.resolve(__dirname, "..", "configs", "xsd");
const mainSchemaPath = path.join(schemaDir, "index.xsd");
// Read the main XSD file as text
let xsdContent = await fs.readFile(mainSchemaPath, "utf8");
// Adjust schemaLocation attributes to use absolute paths
const serializationSchemaPath = path.join(schemaDir, "Serialization.xsd");
const entitiesSchemaPath = path.join(schemaDir, "Entities.xsd");
xsdContent = xsdContent.replace(
/schemaLocation="\.\/Serialization\.xsd"/g,
`schemaLocation="${serializationSchemaPath}"`
);
xsdContent = xsdContent.replace(
/schemaLocation="\.\/Entities\.xsd"/g,
`schemaLocation="${entitiesSchemaPath}"`
);
// Parse the adjusted XSD content
const xsdDoc = XmlDocument.fromString(xsdContent, { url: mainSchemaPath });
// Create a validator from the XSD document
const validator = XsdValidator.fromDoc(xsdDoc);
// Handle both single XML string and array of XML strings
const xmlStrings = Array.isArray(xmlString) ? xmlString : [xmlString];
const errors = [];
for (const xmlStr of xmlStrings) {
const xmlDoc = XmlDocument.fromString(xmlStr);
try {
// Validate the XML document
validator.validate(xmlDoc);
} catch (err) {
// Collect validation errors
errors.push(err.message);
} finally {
// Dispose of the XML document
xmlDoc.dispose();
}
}
// Dispose of the validator and XSD document
validator.dispose();
xsdDoc.dispose();
if (errors.length) {
throw new Error(`Validation failed: ${errors.join(", ")}`);
}
return true;
} catch (err) {
console.error("Validation error:", err);
throw err; // This will trigger the retry
}
},
3,
150
); // 3 retries, 2000ms delay between attempts
}
module.exports = validateXml;
And the error here:
error:
Validation error:
XmlValidateError: Element '{http://www.w3.org/2001/XMLSchema}element', attribute 'type': References from this schema to components in the namespace 'https://pontaj.s3.eu-central-1.amazonaws.com/Serialization.xsd' are not allowed, since not indicated by an import statement.
at XmlValidateError.fromDetails (file:///.../node_modules/libxml2-wasm/lib/validates.mjs:53:16)
at new XsdValidator (file:///.../node_modules/libxml2-wasm/lib/validates.mjs:158:44)
at XsdValidator.fromDoc (file:///...r/node_modules/libxml2-wasm/lib/validates.mjs:196:28)
at /.../validateXml.js:52:48
at async retry (/.../validateXml.js:8:20)
at async validateXml (/.../validateXml.js:21:12)
at async /.../generareRegistru.js:20:29 {
details: [
{
message: "Element '{http://www.w3.org/2001/XMLSchema}element', attribute 'type': References from this schema to components in the namespace 'https://pontaj.s3.eu-central-1.amazonaws.com/Serialization.xsd' are not allowed, since not indicated by an import statement.\n",
line: 22,
col: 0,
file: '/.../configs/xsd/index.xsd'
}
]
} (validateXml.js:82)
Metadata
Metadata
Assignees
Labels
Projects
Status