-
Notifications
You must be signed in to change notification settings - Fork 28
/
index.js
143 lines (133 loc) · 4.67 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/**
* Node.js bindings for XSD validation from libxml
* @module libxml-xsd
*/
var fs = require('fs');
var libxmljs = require('libxmljs-mt');
var binding = require('bindings')('node-libxml-xsd');
/**
* The libxmljs module. Prevents the need for a user's code to require it a second time. Also prevent weird bugs.
*/
exports.libxmljs = libxmljs;
/**
* A compiled schema. Do not call this constructor, instead use parse or parseFile.
*
* store both the source document and the parsed schema
* if we don't store the schema doc it will be deleted by garbage collector and it will result in segfaults.
*
* @constructor
* @param {Document} schemaDoc - XML document source of the schema
* @param {Document} schemaObj - Simple wrapper of a XSD schema
*/
var Schema = function(schemaDoc, schemaObj){
this.schemaDoc = schemaDoc;
this.schemaObj = schemaObj;
};
/**
* Parse a XSD schema
*
* If no callback is given the function will run synchronously and return the result or throw an error.
*
* @param {string|Document} source - The content of the schema as a string or a [libxmljs document]{@link https://github.com/polotek/libxmljs/wiki/Document}
* @param {parseCallback} [callback] - The callback that handles the response. Expects err and Schema object.
* @return {Schema} Only if no callback is given.
*/
exports.parse = function(source, callback) {
// schema can be given as a string or a pre-parsed xml document
if (typeof source === 'string') {
try {
source = libxmljs.parseXml(source);
} catch (err) {
if (callback) return callback(err);
throw err;
}
}
if (callback) {
binding.schemaAsync(source, function(err, schema){
if (err) return callback(err);
callback(null, new Schema(source, schema));
});
} else {
return new Schema(source, binding.schemaSync(source));
}
};
/**
* Callback to the parse function
* @callback parseCallback
* @param {error} [err]
* @param {Schema} [schema]
*/
/**
* Parse a XSD schema
*
* @param {stringPath} sourcePath - The path of the file
* @param {parseFileCallback} callback - The callback that handles the response. Expects err and Schema object.
*/
exports.parseFile = function(sourcePath, callback) {
fs.readFile(sourcePath, 'utf8', function(err, data){
if (err) return callback(err);
exports.parse(data, callback);
});
};
/**
* Callback to the parseFile function
* @callback parseFileCallback
* @param {error} [err]
* @param {Schema} [schema]
*/
/**
* Validate a XML document over a schema
*
* If no callback is given the function will run synchronously and return the result or throw an error.
*
* @param {string|Document} source - The XML content to validate with the schema, to be given as a string or a [libxmljs document]{@link https://github.com/polotek/libxmljs/wiki/Document}
* @param {Schema~validateCallback} [callback] - The callback that handles the response. Expects err and an array of validation errors, null if none.
* @return {string|Document} Only if no callback is given. An array of validation errors, null if none.
*/
Schema.prototype.validate = function(source, callback) {
// xml can be given as a string or a pre-parsed xml document
var outputString = false;
if (typeof source === 'string') {
try {
source = libxmljs.parseXml(source);
} catch (err) {
if (callback) return callback(err);
throw err;
}
outputString = true;
}
if (callback) {
binding.validateAsync(this.schemaObj, source, function(err, validationErrors){
if (err) return callback(err);
return callback(null, validationErrors.length > 0 ? validationErrors : null);
});
} else {
var validationErrors = binding.validateSync(this.schemaObj, source);
return validationErrors.length > 0 ? validationErrors : null;
}
};
/**
* Callback to the Schema.validate function
* @callback Schema~validateCallback
* @param {error} [err] - Error when attempting to validate (not a validation error).
* @param {array} [validationErrors] - A array of errors from validating the schema, null if none.
*/
/**
* Apply a schema to a XML file
*
* @param {string} sourcePath - The path of the file to read
* @param {Schema~validateFileCallback} callback The callback that handles the response. Expects err and an array of validation errors null if none.
*/
Schema.prototype.validateFile = function(sourcePath, callback) {
var that = this;
fs.readFile(sourcePath, 'utf8', function(err, data){
if (err) return callback(err);
that.validate(data, callback);
});
};
/**
* Callback to the Schema.validateFile function
* @callback Schema~validateFileCallback
* @param {error} [err] - Error when attempting to validate (not a validation error).
* @param {array} [validationErrors] - A array of errors from validating the schema, null if none.
*/