xml-toolkit 0.0.8 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -1
- package/index.js +10 -6
- package/lib/MoxyLikeJsonEncoder.js +41 -23
- package/lib/NamespacePrefixesMap.js +57 -0
- package/lib/XMLMarshaller.js +363 -0
- package/lib/XMLNode.js +9 -3
- package/lib/XMLSchema.js +103 -0
- package/lib/XMLSchemata.js +143 -0
- package/package.json +6 -3
- package/test/commons/dom-gosuslugi-ru-smev3-common.xsd +465 -0
- package/test/dom-gosuslugi-ru-smev3-debt-responses.xsd +776 -0
- package/test/test.js +118 -3
package/lib/XMLSchema.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const XMLSchema = class extends Map {
|
|
2
|
+
|
|
3
|
+
constructor (parent, targetNamespace) {
|
|
4
|
+
|
|
5
|
+
super ()
|
|
6
|
+
|
|
7
|
+
this.parent = parent
|
|
8
|
+
this.targetNamespace = targetNamespace
|
|
9
|
+
|
|
10
|
+
this.isDefaultElementFormQualified = true
|
|
11
|
+
this.isAttributeElementFormQualified = false
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
add (node, options = {}) {
|
|
16
|
+
|
|
17
|
+
if (node.elementFormDefault === 'unqualified') this.isDefaultElementFormQualified = false
|
|
18
|
+
if (node.attributeFormDefault === 'qualified') this.isAttributeElementFormQualified = true
|
|
19
|
+
|
|
20
|
+
for (const type of [
|
|
21
|
+
|
|
22
|
+
'element',
|
|
23
|
+
'complexType',
|
|
24
|
+
'simpleType',
|
|
25
|
+
|
|
26
|
+
]) if (type in node) {
|
|
27
|
+
|
|
28
|
+
let list = node [type]
|
|
29
|
+
|
|
30
|
+
if (!Array.isArray (list)) list = [list]
|
|
31
|
+
|
|
32
|
+
for (const item of list) {
|
|
33
|
+
|
|
34
|
+
delete item.annotation
|
|
35
|
+
|
|
36
|
+
item._type = type
|
|
37
|
+
|
|
38
|
+
this.copyTargetNamespace (item)
|
|
39
|
+
|
|
40
|
+
this.set (item.name, item)
|
|
41
|
+
|
|
42
|
+
this.parent.register (item.name, this.targetNamespace)
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
copyTargetNamespace (o) {
|
|
51
|
+
|
|
52
|
+
if (typeof o !== 'object') return
|
|
53
|
+
|
|
54
|
+
if (Array.isArray (o)) {
|
|
55
|
+
|
|
56
|
+
for (const v of o) this.copyTargetNamespace (v)
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
|
|
61
|
+
o.targetNamespace = this.targetNamespace
|
|
62
|
+
|
|
63
|
+
for (const v of Object.values (o)) this.copyTargetNamespace (v)
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
XMLSchema.adjustNode = node => {
|
|
72
|
+
|
|
73
|
+
if (node.children) node.children = node.children.filter (i => i.localName !== 'annotation')
|
|
74
|
+
|
|
75
|
+
const {attributes, namespacesMap} = node, splitNs = name => {
|
|
76
|
+
|
|
77
|
+
if (!attributes.has (name)) return
|
|
78
|
+
|
|
79
|
+
const [local, prefix] = attributes.get (name).split (':').reverse ()
|
|
80
|
+
|
|
81
|
+
attributes.set (name, [local, namespacesMap.get (prefix)])
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
switch (node.localName) {
|
|
86
|
+
|
|
87
|
+
case 'attribute':
|
|
88
|
+
case 'element':
|
|
89
|
+
splitNs ('type')
|
|
90
|
+
break
|
|
91
|
+
|
|
92
|
+
case 'extension':
|
|
93
|
+
case 'restriction':
|
|
94
|
+
splitNs ('base')
|
|
95
|
+
break
|
|
96
|
+
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return node
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
module.exports = XMLSchema
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
const assert = require ('assert')
|
|
2
|
+
|
|
3
|
+
const fs = require ('fs')
|
|
4
|
+
const path = require ('path')
|
|
5
|
+
|
|
6
|
+
const XMLReader = require ('./XMLReader.js')
|
|
7
|
+
const XMLNode = require ('./XMLNode.js')
|
|
8
|
+
const XMLSchema = require ('./XMLSchema.js'), {adjustNode} = XMLSchema
|
|
9
|
+
const NamespacePrefixesMap = require ('./NamespacePrefixesMap.js')
|
|
10
|
+
const XMLMarshaller = require ('./XMLMarshaller.js')
|
|
11
|
+
|
|
12
|
+
const IDX = Symbol ('_index')
|
|
13
|
+
|
|
14
|
+
const XMLSchemata = class extends Map {
|
|
15
|
+
|
|
16
|
+
constructor () {
|
|
17
|
+
|
|
18
|
+
super ()
|
|
19
|
+
|
|
20
|
+
this [IDX] = new Map ()
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
register (name, targetNamespace) {
|
|
25
|
+
|
|
26
|
+
const idx = this [IDX]
|
|
27
|
+
|
|
28
|
+
if (!idx.has (name)) idx.set (name, new Set ())
|
|
29
|
+
|
|
30
|
+
idx.get (name).add (targetNamespace)
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
getByReference (ref) {
|
|
35
|
+
|
|
36
|
+
const [localName, namespaceURI] = ref
|
|
37
|
+
|
|
38
|
+
if (namespaceURI === 'http://www.w3.org/2001/XMLSchema') return {
|
|
39
|
+
_type: 'simpleType',
|
|
40
|
+
name: localName
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return this.get (namespaceURI).get (localName)
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
getSchemaByLocalName (localName) {
|
|
48
|
+
|
|
49
|
+
const ns = this [IDX].get (localName)
|
|
50
|
+
|
|
51
|
+
if (!ns) throw new Error ('Unknown name: ' + localName)
|
|
52
|
+
|
|
53
|
+
if (ns.size !== 1) throw new Error ('Ambiguous name ' + localName + ' belongs to: ' + Array.from (ns.values ()).map (s => `"${s}"`).join (', '))
|
|
54
|
+
|
|
55
|
+
for (const uri of ns) return this.get (uri)
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getNamespacePrefixesMap (o) {
|
|
60
|
+
|
|
61
|
+
return new NamespacePrefixesMap (this, o)
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
createMarshaller (localName, namespaceURI) {
|
|
66
|
+
|
|
67
|
+
if (arguments.length === 1) namespaceURI = this.getSchemaByLocalName (localName).targetNamespace
|
|
68
|
+
|
|
69
|
+
return new XMLMarshaller (this, localName, namespaceURI)
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
stringify (o) {
|
|
74
|
+
|
|
75
|
+
assert.strictEqual (typeof o, 'object')
|
|
76
|
+
|
|
77
|
+
assert.strictEqual (Object.keys (o).length, 1)
|
|
78
|
+
|
|
79
|
+
for (let [localName, content] of Object.entries (o))
|
|
80
|
+
|
|
81
|
+
return this.createMarshaller (localName).stringify (content)
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async addSchema (node, options = {}) {
|
|
86
|
+
|
|
87
|
+
let {targetNamespace} = node; if (!targetNamespace) targetNamespace = options.targetNamespace
|
|
88
|
+
|
|
89
|
+
if (!this.has (targetNamespace)) this.set (targetNamespace, new XMLSchema (this, targetNamespace))
|
|
90
|
+
|
|
91
|
+
let imp = node.import; if (imp) {
|
|
92
|
+
|
|
93
|
+
const {addLocation} = options
|
|
94
|
+
|
|
95
|
+
if (!Array.isArray (imp)) imp = [imp]
|
|
96
|
+
|
|
97
|
+
for (const {schemaLocation, namespace} of imp) await addLocation (schemaLocation, namespace)
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.get (targetNamespace).add (node)
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async addFile (fn, options = {}) {
|
|
106
|
+
|
|
107
|
+
const dirname = path.dirname (fn), that = this, addLocation = async function (schemaLocation, namespace) {
|
|
108
|
+
|
|
109
|
+
await that.addFile (path.join (dirname, schemaLocation), options = {targetNamespace: namespace})
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const {targetNamespace} = options, mapper = XMLNode.toObject ({})
|
|
114
|
+
|
|
115
|
+
for await (const node of
|
|
116
|
+
|
|
117
|
+
new XMLReader ({
|
|
118
|
+
filterElements: e => e.namespaceURI === 'http://www.w3.org/2001/XMLSchema',
|
|
119
|
+
map: adjustNode,
|
|
120
|
+
})
|
|
121
|
+
.process (fs.createReadStream (fn))
|
|
122
|
+
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
if (node.localName === 'schema')
|
|
126
|
+
|
|
127
|
+
await this.addSchema (mapper (node), {addLocation, targetNamespace})
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
XMLSchemata.fromFile = async function (fn, options = {}) {
|
|
134
|
+
|
|
135
|
+
let xs = new XMLSchemata ()
|
|
136
|
+
|
|
137
|
+
await xs.addFile (fn, options)
|
|
138
|
+
|
|
139
|
+
return xs
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = XMLSchemata
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xml-toolkit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Collection of classes for dealing with XML",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "node test/test.js"
|
|
7
|
+
"test": "node test/test.js"
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -20,5 +20,8 @@
|
|
|
20
20
|
"bugs": {
|
|
21
21
|
"url": "https://github.com/do-/node-xml-toolkit/issues"
|
|
22
22
|
},
|
|
23
|
-
"homepage": "https://github.com/do-/node-xml-toolkit#readme"
|
|
23
|
+
"homepage": "https://github.com/do-/node-xml-toolkit#readme",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"string-escape-map": "^1.0.0"
|
|
26
|
+
}
|
|
24
27
|
}
|