Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import multiple schema files needed for validation #8

Open
hubgit opened this issue Apr 18, 2015 · 14 comments
Open

Import multiple schema files needed for validation #8

hubgit opened this issue Apr 18, 2015 · 14 comments

Comments

@hubgit
Copy link

hubgit commented Apr 18, 2015

If a schema file imports other modules, they need to be in the same pseudo-filesystem for xmllint to access.

I've had a go at this in hubgit@2cbc559 (which also includes changes to allow all the command line arguments to be passed into validateXML along with the list of files to be imported, and returns stdout and stderr separately so that the XML in stdout can be used subsequently).

@sterpe
Copy link
Collaborator

sterpe commented Apr 20, 2015

I'm a bit unclear. Your changes break using xmllint within node.js completely.

I'm also unclear why this API proposal offers over the previous options object?

Edit: Okay I get what you are trying to solve.

If you want to support unsupported command line flags, it seems like you could add support for those flags within the existing API's {options}, or am I missing something? It also seem like we could pass in any schema file imports as an array property there as well.

@sterpe
Copy link
Collaborator

sterpe commented Apr 20, 2015

To be clear: I'm totally for the capability this provides, but xmllint should still work in node & the solution should extend the existing api in a fully backwards compatible way.

@hubgit
Copy link
Author

hubgit commented Apr 20, 2015

Basiclaly I'm just trying to make the interface as simple as possible (and in my case this is for a Polymer element, so doesn't need to support node). The aim is to make calling xmllint(args, files) as close as possible to running xmllint [args] file on the command line (except that the schema/DTD files need to be passed in as pairs of filenames and data, as they're not fetched automatically) - that's why this isn't a pull request :)

I managed to simplify the interface down quite a bit in the end, so it's perhaps a bit clearer what's going on now:
https://github.com/hubgit/xml.js/blob/dtd-validation/src/wrapper.js
https://github.com/hubgit/xml.js/blob/dtd-validation/src/pre.js

@sterpe
Copy link
Collaborator

sterpe commented Apr 20, 2015

I will look into supporting this capability as well.

Sent from my iPhone

On Apr 20, 2015, at 6:13 AM, Alf Eaton [email protected] wrote:

Basiclaly I'm just trying to make the interface as simple as possible (and in my case this is for a Polymer element, so doesn't need to support node). The aim is to make calling xmllint(args, files) as close as possible to running xmllint [args] file on the command line (except that the schema/DTD files used need to be passed in as pairs of filenames and data, as they're not fetched automatically) - that's why this isn't a pull request :)

I managed to simplify the interface down quite a bit in the end, so it's perhaps a bit clearer what's going on now:
https://github.com/hubgit/xml.js/blob/dtd-validation/src/wrapper.js
https://github.com/hubgit/xml.js/blob/dtd-validation/src/pre.js


Reply to this email directly or view it on GitHub.

@mrft
Copy link

mrft commented Jun 5, 2015

I am trying to use xmllint.js in the browser for validation, but I cannot find a clear explanation on how this should be done in the readme.

This seems related, so I thought I'd add the question here: could you add an explanation, or a clear example to the readme that explains how to use this when you have a schema that imports other schema's?

@sterpe
Copy link
Collaborator

sterpe commented Jun 5, 2015

I think that @hubgit was trying to solve the schema that imports other schemas in the browser. I was reluctant to pull in those changes because they break the library in node.js. If that's not an issue of concern you might checkout his fork (links above).

Generally, speaking you will need to do some type of transformation to compile & run xml.js in the browser: i.e., webpack, browserify, etc.

@hubgit
Copy link
Author

hubgit commented Jun 5, 2015

@mrft You can see how I was using xmllint.js to validate against a DTD in this branch (using the version of xml.js linked above). It requires listing all the DTD files that would need to be loaded as imports, and making sure they're all loaded into the pseudo-filesystem in advance.

@IceOnFire
Copy link

Hi there, is the project still alive? I see that Microsoft uses xml.js to validate Office add-in schemas (see projects scaffolded with this generator), but apparently it doesn't work properly when the main XSD imports other subschemas.

There seems to be a difference between the native xmllint executable and the JS version:

  • xmllint --noout --schema schemas/OfficeAppManifestV1_1.xsd manifest.xml works
  • var result = xmllint.validateXML({xml: fs.readFileSync('manifest.xml'), schema: fs.readFileSync('schemas/OfficeAppManifestV1_1.xsd')}) returns an error because the main schema cannot find its references

The same behaviour happens if I put all schemas in the project root, so it should not be related to relative paths.

@sterpe
Copy link
Collaborator

sterpe commented Apr 14, 2016

@IceOnFire The schema references are not available on the virtual filesystem that emscripten loads from. @hubgit did some work on this above.

@ikin77
Copy link

ikin77 commented Apr 19, 2016

I found the way to do it, in case anybody needs it:

You have to pass all XSDs in a array list:

var Module = {
xml: stringWithXMLToCheck,
schema: [xsdString1, xsdString2, .....],
};

The main XSD must be the last in the list. You also have to modify all XSDs in imports, in "schemaLocation". If for instance the main XSD imports the first XSD in the list, the value is schemaLocation="file_0.xsd". So, the order in the array must match the values you change in all XSD files.

Best regards!!!!

                var errors = xmllint.validateXML(Module).errors;

@IceOnFire
Copy link

Thanks @ikin77, it works! ^_^

I think I'll checkout also @hubgit's fork though, since changing paths on my XSDs gives me the chills.

@lapo-luchini
Copy link

It would be nice if it was possible to automatically detect that the requested location was already included in a previous element in the schema array.

@lapo-luchini
Copy link

I'm using this work-around to automatically link schemas one another:

const
    reLoc1 = /targetNamespace="([^"]+)"/,
    reLoc2 = /(\bimport\s+namespace="([^"]+)"\s+schemaLocation=")[^"]+/g,
    loc = {};
opts.schema = opts.schema.map((s, idx) => {
    // detect namespace defined by this schema
    const ns = reLoc1.exec(s);
    if (ns)
        loc[ns[1]] = 'file_' + idx + '.xsd';
    // redirect imports of a known schema to the right file
    s = s.replace(reLoc2, (all, base, ns) => {
        const file = loc[ns];
        if (!file) return;
        return base + file;
    });
    return s;
});

@hmuus
Copy link

hmuus commented Apr 9, 2020

I played around a bit, nice piece of work!
I'm wondering where to do different language support as well as more verbose return messages. Looking at the result:

"test.xml:27: element CreDtTm: Schemas validity error : Element '{urn:iso:std:iso:20022:tech:xsd:camt.086.001.01}CreDtTm': '34' is not a valid value of the atomic type '{urn:iso:std:iso:20022:tech:xsd:camt.086.001.01}ISODateTime'.
test.xml fails to validate"

I would love to see not just ":27:", but at least ":line 27:". For one liner something like ":position 324:".

I tried to get into the code, but after a day of poking around I give up. Any idea where I can hook in?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants