-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathincludeExternalDocument.js
109 lines (94 loc) · 3.65 KB
/
includeExternalDocument.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
// jshint node:true
// jshint shadow:true
module.exports = modifyTest;
var fs = require('fs');
var xpath = require('xpath');
var dom = require('xmldom').DOMParser;
var path_module = require('path');
var loadedExternalDocuments = {};
function modifyTest(test, resourceDir) {
var matches = /=document\((\'[-_.A-Za-z0-9]+\'|\"[-_.A-Za-z0-9]+\")\)/.exec(test);
while (matches) {
// String processing to select the non-regular predicate expression
var equalInd = test.indexOf(matches[0]);
var start = equalInd;
var bracketDepth = 0;
for (var i = equalInd; i >= 0; i--) {
if (!bracketDepth && (test[i] === '[' || test[i] === ' ')) {
start = i + 1;
break;
}
if (test[i] === ']') {
bracketDepth++;
}
else if (test[i] === '[') {
bracketDepth--;
}
}
var end = test.length;
bracketDepth = 0;
for (var i = start + matches[0].length; i < test.length; i++) {
if (!bracketDepth && (test[i] === ']' || test[i] === ' ')) {
end = i;
break;
}
if (test[i] === '[') {
bracketDepth++;
}
else if (test[i] === ']') {
bracketDepth--;
}
}
var predicate = test.slice(start, end);
// Load external doc (load from "cache" if already loaded)
var filepath = matches[1].slice(1, -1);
var externalDoc;
if (!loadedExternalDocuments[filepath]) {
var externalXml = null;
try {
externalXml = fs.readFileSync(path_module.join(resourceDir, filepath), 'utf-8').toString();
}
catch (err) {
throw new Error('No such file \'' + filepath + '\'');
}
externalDoc = new dom().parseFromString(externalXml);
loadedExternalDocuments[filepath] = externalDoc;
}
else {
externalDoc = loadedExternalDocuments[filepath];
}
var externalXpath = test.slice(equalInd + matches[0].length, end);
// Extract namespaces
var defaultNamespaceKey = /([^(<>.\/)]+):[^(<>.\/)]+/.exec(externalXpath)[1];
var externalNamespaceMap = externalDoc.lastChild._nsMap;
var namespaceMap = {};
for (var key in externalNamespaceMap) {
if (externalNamespaceMap.hasOwnProperty(key)) {
if (key) {
namespaceMap[key] = externalNamespaceMap[key];
}
}
}
namespaceMap[defaultNamespaceKey] = externalNamespaceMap[''];
var externalSelect = xpath.useNamespaces(namespaceMap);
// Create new predicate from extract values
var values = [];
var externalResults = externalSelect(externalXpath, externalDoc);
for (var i = 0; i < externalResults.length; i++) {
values.push(externalResults[i].value);
}
var lhv = predicate.slice(0, predicate.indexOf('=document('));
var newPredicate = '(';
for (var i = 0; i < values.length; i++) {
newPredicate += lhv + '=\'' + values[i] + '\'';
if (i < values.length - 1) {
newPredicate += ' or ';
}
}
newPredicate += ')';
// Replace test
test = test.slice(0, start) + newPredicate + test.slice(end);
matches = /@[^\[\]]+=document\((\'[-_.A-Za-z0-9]+\'|\"[-_.A-Za-z0-9]+\")\)/.exec(test);
}
return test;
}