forked from tmpvar/node-xsd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
124 lines (104 loc) · 2.6 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
var sax = require('sax');
var fs = require('fs');
var Stream = require('stream').Stream;
var xsd = {};
xsd.stringToFlatJSON = function(str, callback) {
var ret = {};
var errors = [];
// if your xsd is hosed, so are you.
var parser = sax.parser(true);
var trail = [];
var depth = 0;
var pending = {};
var lastNode = null;
var ignore = [
'xs:schema', // TODO: process references
'xs:import', // TODO: fetch and process
'xs:annotation',
'xs:documentation'
];
var pad = function() {
var ret = '';
var total = trail.length;
while (total--) {
ret += ' ';
}
return ret;
}
var parentIgnored = false;
// Handle parser events
parser.onopentag = function(node) {
if (ignore.indexOf(node.name) > -1 || parentIgnored) {
parentIgnored = true;
return;
}
node = JSON.parse(JSON.stringify(node));
var nameParts = node.name.split(':');
var xsName = nameParts.pop();
var prefix = nameParts.pop();
var name = node.name;
if (node.attributes && node.attributes.name) {
name = prefix + ':' + node.attributes.name;
}
var currentNode = {
type : node.name,
name : name
};
if (node.attributes) {
Object.keys(node.attributes).forEach(function(key) {
// skip the name attribute as it's the key of the ret
if (key === 'name') {
return;
}
// skip the id if it's the same as the localName
if (key === 'id' && node.attributes.name === node.attributes.id) {
return;
}
currentNode[key] = node.attributes[key];
});
delete node.attributes;
}
if (trail.length === 0) {
lastNode = currentNode
ret[name] = lastNode;
lastNode.derivedFrom = [];
trail.unshift(currentNode);
} else {
trail.unshift(currentNode);
}
depth++;
};
parser.onclosetag = function(tagName) {
parentIgnored = false;
if (ignore.indexOf(tagName) > -1) {
return;
}
depth--;
if (depth<1) {
// get rid of the root
trail.pop();
if (trail.length > 0) {
lastNode.derivedFrom = trail.concat([]);
} else {
delete lastNode.derivedFrom;
}
trail = [];
depth = 0;
}
}
parser.onerror = function(err) {
errors.push(err);
};
parser.onend = function() {
callback(errors, ret);
};
parser.write(str).close();
};
xsd.fileToFlatJSON = function(filename, callback) {
fs.readFile(filename, function(err, data) {
if (!err) {
xsd.stringToFlatJSON(data.toString(), callback);
}
});
};
module.exports = xsd;