Open SKalt opened 1 week ago
Let me summarize your requirements:
There may be some options you can use to make the code simpler.
And by providing the path of the master XSD in the options.url
parameter of XmlDocument.fromBuffer
,
libxml2 will figure out the actual paths of imported/included XSD files, and the provider in nodejs.mjs could handle it.
This requires minimal code, but you need to modify the XSD files.
The code will be like
const prefixMapping = new {
"http://foo.example.com/schema-a": "./xsds/schema-a",
"http://bar.example.com/schema-b": "./xsds/schema-b",
}
const urlMapping = Object.fromEntry(
Object.entries(prefixMapping)
.flatMap((url, dir) =>
globSync(dir + "/**/*.xsd") // find all xsd file
.map(p => [`${url}/${path.relative(dir, p)}`, p]) // url -> local path
)
)
then your provider could be like
match(url) {
return Object.hasOwn(urlMapping, url)
}
open(url) {
return fs.openSync(urlMapping[url]);
}
...
An alternative option can be caching XSD content in memory Buffer
, so it won't need to read from disk every time.
It may benefit if your app reads XSD multiple times.
Modifying the source xsds isn't an option for me since I'm trying to keep them remain byte-for-byte identical some authoritative schema documents.
The latter example is great! I'd be interested in how the caching you proposed would work, too.
I’ve come to realize that the task is more intricate than I initially anticipated.
urlMapping
, you create an object xsdByUrl
that maps URLs to Buffers. To achieve this, you assign the result of fs.readFileSync(p)
as the values.However, since libxml2 may read the file in multiple truncks, you need to maintain a context object for the file pointer. Additionally, the WASM library cannot hold references to JavaScript objects, so you must use a number to represent the context object.
Essentially, you need a Map<number, Context>
object to manage the file pointer.
open
callback, create a new context object.read
callback, copy the data and update the file pointer in the context object.close
callback, remove the context object.It would be convenient if libxml2-wasm provided a helper function for handling such scenarios. 🤔
I'm trying to use this library to validate an XML schema that has many
xs:include
references to different URLs. I've saved local copies of each of the referenced*.xsd
s in a local directory:I'd like a convenient way to construct an object that implements the
XmlInputProvider
interface and handles different hosts.Here's what I ended up implementing: