xslt-processor 1.0.0 → 1.1.0

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.
Files changed (247) hide show
  1. package/LICENSE +165 -0
  2. package/README.md +29 -2
  3. package/constants.js.map +1 -0
  4. package/dom/functions.d.ts +15 -0
  5. package/{src/dom → dom}/functions.js +88 -43
  6. package/dom/functions.js.map +1 -0
  7. package/{src/dom → dom}/index.d.ts +1 -0
  8. package/{src/dom → dom}/index.js +1 -0
  9. package/dom/index.js.map +1 -0
  10. package/{src/dom → dom}/util.d.ts +0 -21
  11. package/dom/util.js +175 -0
  12. package/dom/util.js.map +1 -0
  13. package/{src/dom → dom}/xdocument.d.ts +3 -2
  14. package/dom/xdocument.js +71 -0
  15. package/dom/xdocument.js.map +1 -0
  16. package/dom/xml-functions.d.ts +46 -0
  17. package/dom/xml-functions.js +317 -0
  18. package/dom/xml-functions.js.map +1 -0
  19. package/{src/dom → dom}/xmltoken.js +25 -25
  20. package/dom/xmltoken.js.map +1 -0
  21. package/dom/xnode.d.ts +62 -0
  22. package/{src/dom → dom}/xnode.js +144 -91
  23. package/dom/xnode.js.map +1 -0
  24. package/index.d.ts +4 -4
  25. package/index.js +6 -5
  26. package/index.js.map +1 -1
  27. package/package.json +31 -10
  28. package/umd/constants.d.ts +8 -0
  29. package/umd/dom/functions.d.ts +15 -0
  30. package/umd/dom/index.d.ts +4 -0
  31. package/umd/dom/util.d.ts +26 -0
  32. package/umd/dom/xdocument.d.ts +16 -0
  33. package/umd/dom/xml-functions.d.ts +46 -0
  34. package/umd/dom/xmltoken.d.ts +12 -0
  35. package/umd/dom/xnode.d.ts +62 -0
  36. package/umd/index.d.ts +4 -0
  37. package/{src → umd}/xpath/expr-context.d.ts +6 -7
  38. package/umd/xpath/expressions/function-call-expr.d.ts +49 -0
  39. package/{src → umd}/xpath/expressions/location-expr.d.ts +1 -1
  40. package/{src → umd}/xpath/expressions/step-expr.d.ts +1 -1
  41. package/umd/xpath/node-test-element-or-attribute.d.ts +5 -0
  42. package/{src → umd}/xpath/node-test-name.d.ts +1 -1
  43. package/{src → umd}/xpath/xpath.d.ts +12 -5
  44. package/umd/xslt-processor.js +16 -0
  45. package/umd/xslt-processor.js.map +1 -0
  46. package/umd/xslt.d.ts +133 -0
  47. package/xpath/expr-context.d.ts +26 -0
  48. package/{src/xpath → xpath}/expr-context.js +41 -42
  49. package/xpath/expr-context.js.map +1 -0
  50. package/xpath/expressions/binary-expr.d.ts +10 -0
  51. package/{src/xpath → xpath}/expressions/binary-expr.js +65 -47
  52. package/xpath/expressions/binary-expr.js.map +1 -0
  53. package/xpath/expressions/expression.d.ts +4 -0
  54. package/xpath/expressions/expression.js +10 -0
  55. package/xpath/expressions/expression.js.map +1 -0
  56. package/xpath/expressions/filter-expr.d.ts +9 -0
  57. package/xpath/expressions/filter-expr.js +53 -0
  58. package/xpath/expressions/filter-expr.js.map +1 -0
  59. package/xpath/expressions/function-call-expr.d.ts +49 -0
  60. package/{src/xpath → xpath}/expressions/function-call-expr.js +160 -155
  61. package/xpath/expressions/function-call-expr.js.map +1 -0
  62. package/xpath/expressions/index.d.ts +13 -0
  63. package/xpath/expressions/index.js.map +1 -0
  64. package/xpath/expressions/literal-expr.d.ts +7 -0
  65. package/xpath/expressions/literal-expr.js +34 -0
  66. package/xpath/expressions/literal-expr.js.map +1 -0
  67. package/xpath/expressions/location-expr.d.ts +14 -0
  68. package/xpath/expressions/location-expr.js +94 -0
  69. package/xpath/expressions/location-expr.js.map +1 -0
  70. package/xpath/expressions/number-expr.d.ts +7 -0
  71. package/xpath/expressions/number-expr.js +34 -0
  72. package/xpath/expressions/number-expr.js.map +1 -0
  73. package/xpath/expressions/path-expr.d.ts +9 -0
  74. package/xpath/expressions/path-expr.js +52 -0
  75. package/xpath/expressions/path-expr.js.map +1 -0
  76. package/xpath/expressions/predicate-expr.d.ts +8 -0
  77. package/xpath/expressions/predicate-expr.js +43 -0
  78. package/xpath/expressions/predicate-expr.js.map +1 -0
  79. package/xpath/expressions/step-expr.d.ts +14 -0
  80. package/{src/xpath → xpath}/expressions/step-expr.js +68 -51
  81. package/xpath/expressions/step-expr.js.map +1 -0
  82. package/xpath/expressions/token-expr.d.ts +7 -0
  83. package/xpath/expressions/token-expr.js +34 -0
  84. package/xpath/expressions/token-expr.js.map +1 -0
  85. package/xpath/expressions/unary-minus-expr.d.ts +8 -0
  86. package/xpath/expressions/unary-minus-expr.js +34 -0
  87. package/xpath/expressions/unary-minus-expr.js.map +1 -0
  88. package/xpath/expressions/union-expr.d.ts +9 -0
  89. package/xpath/expressions/union-expr.js +51 -0
  90. package/xpath/expressions/union-expr.js.map +1 -0
  91. package/xpath/expressions/variable-expr.d.ts +7 -0
  92. package/xpath/expressions/variable-expr.js +33 -0
  93. package/xpath/expressions/variable-expr.js.map +1 -0
  94. package/xpath/index.d.ts +9 -0
  95. package/xpath/index.js.map +1 -0
  96. package/xpath/node-test-any.d.ts +5 -0
  97. package/xpath/node-test-any.js +15 -0
  98. package/xpath/node-test-any.js.map +1 -0
  99. package/{src/xpath/node-test-element-or-attribute.d.ts → xpath/node-test-comment.d.ts} +1 -1
  100. package/xpath/node-test-comment.js +15 -0
  101. package/xpath/node-test-comment.js.map +1 -0
  102. package/xpath/node-test-element-or-attribute.d.ts +5 -0
  103. package/xpath/node-test-element-or-attribute.js +16 -0
  104. package/xpath/node-test-element-or-attribute.js.map +1 -0
  105. package/xpath/node-test-name.d.ts +8 -0
  106. package/xpath/node-test-name.js +22 -0
  107. package/xpath/node-test-name.js.map +1 -0
  108. package/xpath/node-test-nc.d.ts +7 -0
  109. package/xpath/node-test-nc.js +17 -0
  110. package/xpath/node-test-nc.js.map +1 -0
  111. package/xpath/node-test-pi.d.ts +6 -0
  112. package/{src/xpath → xpath}/node-test-pi.js +8 -7
  113. package/xpath/node-test-pi.js.map +1 -0
  114. package/xpath/node-test-text.d.ts +4 -0
  115. package/xpath/node-test-text.js +15 -0
  116. package/xpath/node-test-text.js.map +1 -0
  117. package/xpath/tokens.d.ts +231 -0
  118. package/{src/xpath → xpath}/tokens.js +5 -5
  119. package/xpath/tokens.js.map +1 -0
  120. package/xpath/values/boolean-value.d.ts +9 -0
  121. package/xpath/values/boolean-value.js +24 -0
  122. package/xpath/values/boolean-value.js.map +1 -0
  123. package/xpath/values/index.d.ts +4 -0
  124. package/xpath/values/index.js.map +1 -0
  125. package/xpath/values/node-set-value.d.ts +9 -0
  126. package/xpath/values/node-set-value.js +28 -0
  127. package/xpath/values/node-set-value.js.map +1 -0
  128. package/xpath/values/number-value.d.ts +9 -0
  129. package/xpath/values/number-value.js +24 -0
  130. package/xpath/values/number-value.js.map +1 -0
  131. package/xpath/values/string-value.d.ts +9 -0
  132. package/{src/xpath → xpath}/values/string-value.js +12 -11
  133. package/xpath/values/string-value.js.map +1 -0
  134. package/xpath/xpath-grammar-rules.d.ts +68 -0
  135. package/xpath/xpath-grammar-rules.js.map +1 -0
  136. package/xpath/xpath.d.ts +105 -0
  137. package/{src/xpath → xpath}/xpath.js +267 -266
  138. package/xpath/xpath.js.map +1 -0
  139. package/xpathdebug.d.ts +2 -0
  140. package/{src/xpathdebug.js → xpathdebug.js} +48 -48
  141. package/xpathdebug.js.map +1 -0
  142. package/xslt.d.ts +133 -0
  143. package/xslt.js +643 -0
  144. package/xslt.js.map +1 -0
  145. package/src/constants.js.map +0 -1
  146. package/src/dom/functions.d.ts +0 -3
  147. package/src/dom/functions.js.map +0 -1
  148. package/src/dom/index.js.map +0 -1
  149. package/src/dom/util.js +0 -338
  150. package/src/dom/util.js.map +0 -1
  151. package/src/dom/xdocument.js +0 -47
  152. package/src/dom/xdocument.js.map +0 -1
  153. package/src/dom/xmltoken.js.map +0 -1
  154. package/src/dom/xnode.d.ts +0 -38
  155. package/src/dom/xnode.js.map +0 -1
  156. package/src/xpath/expr-context.js.map +0 -1
  157. package/src/xpath/expressions/binary-expr.js.map +0 -1
  158. package/src/xpath/expressions/expression.js +0 -7
  159. package/src/xpath/expressions/expression.js.map +0 -1
  160. package/src/xpath/expressions/filter-expr.js +0 -35
  161. package/src/xpath/expressions/filter-expr.js.map +0 -1
  162. package/src/xpath/expressions/function-call-expr.d.ts +0 -49
  163. package/src/xpath/expressions/function-call-expr.js.map +0 -1
  164. package/src/xpath/expressions/index.js.map +0 -1
  165. package/src/xpath/expressions/literal-expr.js +0 -16
  166. package/src/xpath/expressions/literal-expr.js.map +0 -1
  167. package/src/xpath/expressions/location-expr.js +0 -76
  168. package/src/xpath/expressions/location-expr.js.map +0 -1
  169. package/src/xpath/expressions/number-expr.js +0 -16
  170. package/src/xpath/expressions/number-expr.js.map +0 -1
  171. package/src/xpath/expressions/path-expr.js +0 -36
  172. package/src/xpath/expressions/path-expr.js.map +0 -1
  173. package/src/xpath/expressions/predicate-expr.js +0 -25
  174. package/src/xpath/expressions/predicate-expr.js.map +0 -1
  175. package/src/xpath/expressions/step-expr.js.map +0 -1
  176. package/src/xpath/expressions/token-expr.js +0 -16
  177. package/src/xpath/expressions/token-expr.js.map +0 -1
  178. package/src/xpath/expressions/unary-minus-expr.js +0 -16
  179. package/src/xpath/expressions/unary-minus-expr.js.map +0 -1
  180. package/src/xpath/expressions/union-expr.js +0 -32
  181. package/src/xpath/expressions/union-expr.js.map +0 -1
  182. package/src/xpath/expressions/variable-expr.js +0 -15
  183. package/src/xpath/expressions/variable-expr.js.map +0 -1
  184. package/src/xpath/index.js.map +0 -1
  185. package/src/xpath/node-test-any.js +0 -14
  186. package/src/xpath/node-test-any.js.map +0 -1
  187. package/src/xpath/node-test-comment.js +0 -12
  188. package/src/xpath/node-test-comment.js.map +0 -1
  189. package/src/xpath/node-test-element-or-attribute.js +0 -12
  190. package/src/xpath/node-test-element-or-attribute.js.map +0 -1
  191. package/src/xpath/node-test-name.js +0 -23
  192. package/src/xpath/node-test-name.js.map +0 -1
  193. package/src/xpath/node-test-nc.js +0 -16
  194. package/src/xpath/node-test-nc.js.map +0 -1
  195. package/src/xpath/node-test-pi.js.map +0 -1
  196. package/src/xpath/node-test-text.js +0 -12
  197. package/src/xpath/node-test-text.js.map +0 -1
  198. package/src/xpath/tokens.js.map +0 -1
  199. package/src/xpath/values/boolean-value.js +0 -23
  200. package/src/xpath/values/boolean-value.js.map +0 -1
  201. package/src/xpath/values/index.js.map +0 -1
  202. package/src/xpath/values/node-set-value.js +0 -27
  203. package/src/xpath/values/node-set-value.js.map +0 -1
  204. package/src/xpath/values/number-value.js +0 -23
  205. package/src/xpath/values/number-value.js.map +0 -1
  206. package/src/xpath/values/string-value.js.map +0 -1
  207. package/src/xpath/xpath-grammar-rules.js.map +0 -1
  208. package/src/xpath/xpath.js.map +0 -1
  209. package/src/xpathdebug.js.map +0 -1
  210. package/src/xslt.d.ts +0 -68
  211. package/src/xslt.js +0 -619
  212. package/src/xslt.js.map +0 -1
  213. package/xslt-processor.js +0 -2
  214. package/xslt-processor.js.map +0 -1
  215. /package/{src/constants.d.ts → constants.d.ts} +0 -0
  216. /package/{src/constants.js → constants.js} +0 -0
  217. /package/{src/dom → dom}/xmltoken.d.ts +0 -0
  218. /package/{src → umd}/xpath/expressions/binary-expr.d.ts +0 -0
  219. /package/{src → umd}/xpath/expressions/expression.d.ts +0 -0
  220. /package/{src → umd}/xpath/expressions/filter-expr.d.ts +0 -0
  221. /package/{src → umd}/xpath/expressions/index.d.ts +0 -0
  222. /package/{src → umd}/xpath/expressions/literal-expr.d.ts +0 -0
  223. /package/{src → umd}/xpath/expressions/number-expr.d.ts +0 -0
  224. /package/{src → umd}/xpath/expressions/path-expr.d.ts +0 -0
  225. /package/{src → umd}/xpath/expressions/predicate-expr.d.ts +0 -0
  226. /package/{src → umd}/xpath/expressions/token-expr.d.ts +0 -0
  227. /package/{src → umd}/xpath/expressions/unary-minus-expr.d.ts +0 -0
  228. /package/{src → umd}/xpath/expressions/union-expr.d.ts +0 -0
  229. /package/{src → umd}/xpath/expressions/variable-expr.d.ts +0 -0
  230. /package/{src → umd}/xpath/index.d.ts +0 -0
  231. /package/{src → umd}/xpath/node-test-any.d.ts +0 -0
  232. /package/{src → umd}/xpath/node-test-comment.d.ts +0 -0
  233. /package/{src → umd}/xpath/node-test-nc.d.ts +0 -0
  234. /package/{src → umd}/xpath/node-test-pi.d.ts +0 -0
  235. /package/{src → umd}/xpath/node-test-text.d.ts +0 -0
  236. /package/{src → umd}/xpath/tokens.d.ts +0 -0
  237. /package/{src → umd}/xpath/values/boolean-value.d.ts +0 -0
  238. /package/{src → umd}/xpath/values/index.d.ts +0 -0
  239. /package/{src → umd}/xpath/values/node-set-value.d.ts +0 -0
  240. /package/{src → umd}/xpath/values/number-value.d.ts +0 -0
  241. /package/{src → umd}/xpath/values/string-value.d.ts +0 -0
  242. /package/{src → umd}/xpath/xpath-grammar-rules.d.ts +0 -0
  243. /package/{src → umd}/xpathdebug.d.ts +0 -0
  244. /package/{src/xpath → xpath}/expressions/index.js +0 -0
  245. /package/{src/xpath → xpath}/index.js +0 -0
  246. /package/{src/xpath → xpath}/values/index.js +0 -0
  247. /package/{src/xpath → xpath}/xpath-grammar-rules.js +0 -0
package/xslt.js ADDED
@@ -0,0 +1,643 @@
1
+ "use strict";
2
+ // Copyright 2023 Design Liquido
3
+ // Copyright 2018 Johannes Wilm
4
+ // Copyright 2005 Google Inc.
5
+ // All Rights Reserved
6
+ //
7
+ //
8
+ // An XSL-T processor written in JavaScript. The implementation is NOT
9
+ // complete; some xsl element are left out.
10
+ //
11
+ // References:
12
+ //
13
+ // [XSLT] XSL-T Specification
14
+ // <http://www.w3.org/TR/1999/REC-xslt-19991116>.
15
+ //
16
+ // [ECMA] ECMAScript Language Specification
17
+ // <http://www.ecma-international.org/publications/standards/Ecma-262.htm>.
18
+ //
19
+ // The XSL processor API has one entry point, the function
20
+ // xsltProcessContext(). It receives as arguments the starting point in the
21
+ // input document as an XPath expression context, the DOM root node of
22
+ // the XSL-T stylesheet, and a DOM node that receives the output.
23
+ //
24
+ // NOTE: Actually, XSL-T processing according to the specification is
25
+ // defined as operation on text documents, not as operation on DOM
26
+ // trees. So, strictly speaking, this implementation is not an XSL-T
27
+ // processor, but the processing engine that needs to be complemented
28
+ // by an XML parser and serializer in order to be complete. Those two
29
+ // are found in the file xml.js.
30
+ //
31
+ //
32
+ // TODO(mesch): add jsdoc comments. Use more coherent naming. Finish
33
+ // remaining XSLT features.
34
+ //
35
+ //
36
+ // Original author: Steffen Meschkat <mesch@google.com>
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.Xslt = void 0;
39
+ var dom_1 = require("./dom");
40
+ var xpath_1 = require("./xpath");
41
+ var constants_1 = require("./constants");
42
+ var values_1 = require("./xpath/values");
43
+ var Xslt = /** @class */ (function () {
44
+ function Xslt() {
45
+ this.xPath = new xpath_1.XPath();
46
+ }
47
+ /**
48
+ * The exported entry point of the XSL-T processor.
49
+ * @param xmlDoc The input document root, as DOM node.
50
+ * @param stylesheet The stylesheet document root, as DOM node.
51
+ * @param parameters Additional parameters to be set as variables.
52
+ * @returns the processed document, as XML text in a string.
53
+ */
54
+ Xslt.prototype.xsltProcess = function (xmlDoc, stylesheet, parameters) {
55
+ var output = new dom_1.XDocument();
56
+ output.appendChild(dom_1.XNode.clone(xmlDoc.childNodes[0], output));
57
+ var expressionContext = new xpath_1.ExprContext([output]);
58
+ if (parameters && typeof parameters === 'object') {
59
+ for (var _i = 0, _a = Object.entries(parameters); _i < _a.length; _i++) {
60
+ var _b = _a[_i], key = _b[0], value = _b[1];
61
+ expressionContext.setVariable(key, new values_1.StringValue(value));
62
+ }
63
+ }
64
+ this.xsltProcessContext(expressionContext, stylesheet, output, parameters);
65
+ var ret = (0, dom_1.xmlTransformedText)(output);
66
+ return ret;
67
+ };
68
+ /**
69
+ * The main entry point of the XSL-T processor, as explained on the top of the file.
70
+ * @param context The input document root, as XPath ExprContext.
71
+ * @param template The stylesheet document root, as DOM node.
72
+ * @param output the root of the generated output, as DOM node.
73
+ * @param _parameters Extra parameters.
74
+ */
75
+ Xslt.prototype.xsltProcessContext = function (context, template, output, _parameters) {
76
+ var outputDocument = (0, dom_1.xmlOwnerDocument)(output);
77
+ if (!this.isXsltElement(template)) {
78
+ this.xsltPassThrough(context, template, output, outputDocument);
79
+ }
80
+ else {
81
+ var name_1, top_1, nameExpr = void 0, node = void 0, select = void 0, value = void 0, nodes = void 0, sortContext = void 0, mode = void 0, templates = void 0, paramContext = void 0, commentData = void 0, commentNode = void 0, test_1, match = void 0, text = void 0;
82
+ switch (template.localName) {
83
+ case 'apply-imports':
84
+ throw "not implemented: ".concat(template.localName);
85
+ case 'apply-templates':
86
+ select = (0, dom_1.xmlGetAttribute)(template, 'select');
87
+ if (select) {
88
+ nodes = this.xPath.xPathEval(select, context).nodeSetValue();
89
+ }
90
+ else {
91
+ nodes = context.nodelist[context.position].childNodes;
92
+ }
93
+ sortContext = context.clone(nodes, 0);
94
+ this.xsltWithParam(sortContext, template);
95
+ this.xsltSort(sortContext, template);
96
+ mode = (0, dom_1.xmlGetAttribute)(template, 'mode');
97
+ top_1 = template.ownerDocument.documentElement;
98
+ templates = [];
99
+ for (var i = 0; i < top_1.childNodes.length; ++i) {
100
+ var c = top_1.childNodes[i];
101
+ var matchAttribute = c.getAttributeValue('match');
102
+ // Avoiding infinite loops.
103
+ if (matchAttribute && matchAttribute.startsWith('/')) {
104
+ continue;
105
+ }
106
+ if (c.nodeType == constants_1.DOM_ELEMENT_NODE &&
107
+ this.isXsltElement(c, 'template') &&
108
+ (!mode || c.getAttributeValue('mode') == mode)) {
109
+ templates.push(c);
110
+ }
111
+ }
112
+ for (var j = 0; j < sortContext.contextSize(); ++j) {
113
+ for (var i = 0; i < templates.length; ++i) {
114
+ this.xsltProcessContext(sortContext.clone(sortContext.nodelist, j), templates[i], output);
115
+ }
116
+ }
117
+ break;
118
+ case 'attribute':
119
+ nameExpr = (0, dom_1.xmlGetAttribute)(template, 'name');
120
+ name_1 = this.xsltAttributeValue(nameExpr, context);
121
+ node = (0, dom_1.domCreateDocumentFragment)(outputDocument);
122
+ this.xsltChildNodes(context, template, node);
123
+ value = (0, dom_1.xmlValue2)(node);
124
+ (0, dom_1.domSetTransformedAttribute)(output, name_1, value);
125
+ break;
126
+ case 'attribute-set':
127
+ throw "not implemented: ".concat(template.localName);
128
+ case 'call-template':
129
+ name_1 = (0, dom_1.xmlGetAttribute)(template, 'name');
130
+ top_1 = template.ownerDocument.documentElement;
131
+ paramContext = context.clone();
132
+ this.xsltWithParam(paramContext, template);
133
+ for (var i = 0; i < top_1.childNodes.length; ++i) {
134
+ var c = top_1.childNodes[i];
135
+ if (c.nodeType == constants_1.DOM_ELEMENT_NODE &&
136
+ this.isXsltElement(c, 'template') &&
137
+ (0, dom_1.domGetAttributeValue)(c, 'name') == name_1) {
138
+ this.xsltChildNodes(paramContext, c, output);
139
+ break;
140
+ }
141
+ }
142
+ break;
143
+ case 'choose':
144
+ this.xsltChoose(context, template, output);
145
+ break;
146
+ case 'comment':
147
+ node = (0, dom_1.domCreateDocumentFragment)(outputDocument);
148
+ this.xsltChildNodes(context, template, node);
149
+ commentData = (0, dom_1.xmlValue)(node);
150
+ commentNode = (0, dom_1.domCreateComment)(outputDocument, commentData);
151
+ output.appendChild(commentNode);
152
+ break;
153
+ case 'copy':
154
+ node = this.xsltCopy(output, context.nodelist[context.position], outputDocument);
155
+ if (node) {
156
+ this.xsltChildNodes(context, template, node);
157
+ }
158
+ break;
159
+ case 'copy-of':
160
+ select = (0, dom_1.xmlGetAttribute)(template, 'select');
161
+ value = this.xPath.xPathEval(select, context);
162
+ if (value.type == 'node-set') {
163
+ nodes = value.nodeSetValue();
164
+ for (var i = 0; i < nodes.length; ++i) {
165
+ this.xsltCopyOf(output, nodes[i], outputDocument);
166
+ }
167
+ }
168
+ else {
169
+ var node_1 = (0, dom_1.domCreateTextNode)(outputDocument, value.stringValue());
170
+ (0, dom_1.domAppendChild)(output, node_1);
171
+ }
172
+ break;
173
+ case 'decimal-format':
174
+ throw "not implemented: ".concat(template.localName);
175
+ case 'element':
176
+ nameExpr = (0, dom_1.xmlGetAttribute)(template, 'name');
177
+ name_1 = this.xsltAttributeValue(nameExpr, context);
178
+ node = (0, dom_1.domCreateElement)(outputDocument, name_1);
179
+ // Adds context children reference to this new node,
180
+ // so then further transformations are also observed
181
+ // by this new node.
182
+ var contextNode = context.nodelist[context.position];
183
+ node.childNodes = contextNode.childNodes;
184
+ node.transformedNodeName = name_1;
185
+ (0, dom_1.domAppendTransformedChild)(output, node);
186
+ this.xsltChildNodes(context, template, node);
187
+ break;
188
+ case 'fallback':
189
+ throw "not implemented: ".concat(template.localName);
190
+ case 'for-each':
191
+ this.xsltForEach(context, template, output);
192
+ break;
193
+ case 'if':
194
+ test_1 = (0, dom_1.xmlGetAttribute)(template, 'test');
195
+ if (this.xPath.xPathEval(test_1, context).booleanValue()) {
196
+ this.xsltChildNodes(context, template, output);
197
+ }
198
+ break;
199
+ case 'import':
200
+ throw "not implemented: ".concat(template.localName);
201
+ case 'include':
202
+ throw "not implemented: ".concat(template.localName);
203
+ case 'key':
204
+ throw "not implemented: ".concat(template.localName);
205
+ case 'message':
206
+ throw "not implemented: ".concat(template.localName);
207
+ case 'namespace-alias':
208
+ throw "not implemented: ".concat(template.localName);
209
+ case 'number':
210
+ throw "not implemented: ".concat(template.localName);
211
+ case 'otherwise':
212
+ throw "error if here: ".concat(template.localName);
213
+ case 'output':
214
+ // Ignored. -- Since we operate on the DOM, and all further use
215
+ // of the output of the XSL transformation is determined by the
216
+ // browser that we run in, this parameter is not applicable to
217
+ // this implementation.
218
+ break;
219
+ case 'preserve-space':
220
+ throw "not implemented: ".concat(template.localName);
221
+ case 'processing-instruction':
222
+ throw "not implemented: ".concat(template.localName);
223
+ case 'sort':
224
+ // just ignore -- was handled by xsltSort()
225
+ break;
226
+ case 'strip-space':
227
+ throw "not implemented: ".concat(template.localName);
228
+ case 'stylesheet':
229
+ case 'transform':
230
+ this.xsltChildNodes(context, template, output);
231
+ break;
232
+ case 'template':
233
+ match = (0, dom_1.xmlGetAttribute)(template, 'match');
234
+ if (match && this.xsltMatch(match, context)) {
235
+ this.xsltChildNodes(context, template, output);
236
+ }
237
+ break;
238
+ case 'text':
239
+ text = (0, dom_1.xmlValue)(template);
240
+ node = (0, dom_1.domCreateTransformedTextNode)(outputDocument, text);
241
+ output.appendTransformedChild(node);
242
+ break;
243
+ case 'value-of':
244
+ select = (0, dom_1.xmlGetAttribute)(template, 'select');
245
+ var attribute = this.xPath.xPathEval(select, context);
246
+ value = attribute.stringValue();
247
+ node = (0, dom_1.domCreateTransformedTextNode)(outputDocument, value);
248
+ context.nodelist[context.position].appendTransformedChild(node);
249
+ break;
250
+ case 'param':
251
+ this.xsltVariable(context, template, false);
252
+ break;
253
+ case 'variable':
254
+ this.xsltVariable(context, template, true);
255
+ break;
256
+ case 'when':
257
+ throw "error if here: ".concat(template.localName);
258
+ case 'with-param':
259
+ throw "error if here: ".concat(template.localName);
260
+ default:
261
+ throw "error if here: ".concat(template.localName);
262
+ }
263
+ }
264
+ };
265
+ /**
266
+ * Implements `xsl:copy` for all node types.
267
+ * @param {XNode} destination the node being copied to, part of output document
268
+ * @param {XNode} source the node being copied, part in input document
269
+ * @param {XDocument} destinationDocument dstDocument
270
+ * @returns {XNode|null} If an element node was created, the element node. Otherwise null.
271
+ */
272
+ Xslt.prototype.xsltCopy = function (destination, source, destinationDocument) {
273
+ if (source.nodeType == constants_1.DOM_ELEMENT_NODE) {
274
+ var node = (0, dom_1.domCreateElement)(destinationDocument, source.nodeName);
275
+ node.transformedNodeName = source.nodeName;
276
+ (0, dom_1.domAppendTransformedChild)(destination, node);
277
+ return node;
278
+ }
279
+ if (source.nodeType == constants_1.DOM_TEXT_NODE) {
280
+ var node = (0, dom_1.domCreateTransformedTextNode)(destinationDocument, source.nodeValue);
281
+ (0, dom_1.domAppendTransformedChild)(destination, node);
282
+ }
283
+ else if (source.nodeType == constants_1.DOM_CDATA_SECTION_NODE) {
284
+ var node = (0, dom_1.domCreateCDATASection)(destinationDocument, source.nodeValue);
285
+ (0, dom_1.domAppendTransformedChild)(destination, node);
286
+ }
287
+ else if (source.nodeType == constants_1.DOM_COMMENT_NODE) {
288
+ var node = (0, dom_1.domCreateComment)(destinationDocument, source.nodeValue);
289
+ (0, dom_1.domAppendTransformedChild)(destination, node);
290
+ }
291
+ else if (source.nodeType == constants_1.DOM_ATTRIBUTE_NODE) {
292
+ (0, dom_1.domSetTransformedAttribute)(destination, source.nodeName, source.nodeValue);
293
+ }
294
+ return null;
295
+ };
296
+ /**
297
+ * Orders the current node list in the input context according to the
298
+ * sort order specified by xsl:sort child nodes of the current
299
+ * template node. This happens before the operation specified by the
300
+ * current template node is executed.
301
+ * @param context TODO
302
+ * @param template TODO
303
+ * @todo case-order is not implemented.
304
+ */
305
+ Xslt.prototype.xsltSort = function (context, template) {
306
+ var sort = [];
307
+ for (var _i = 0, _a = template.childNodes; _i < _a.length; _i++) {
308
+ var c = _a[_i];
309
+ if (c.nodeType == constants_1.DOM_ELEMENT_NODE && this.isXsltElement(c, 'sort')) {
310
+ var select = (0, dom_1.xmlGetAttribute)(c, 'select');
311
+ var expr = this.xPath.xPathParse(select);
312
+ var type = (0, dom_1.xmlGetAttribute)(c, 'data-type') || 'text';
313
+ var order = (0, dom_1.xmlGetAttribute)(c, 'order') || 'ascending';
314
+ sort.push({
315
+ expr: expr,
316
+ type: type,
317
+ order: order
318
+ });
319
+ }
320
+ }
321
+ this.xPath.xPathSort(context, sort);
322
+ };
323
+ /**
324
+ * Evaluates a variable or parameter and set it in the current input
325
+ * context. Implements `xsl:variable`, `xsl:param`, and `xsl:with-param`.
326
+ *
327
+ * @param input TODO
328
+ * @param template TODO
329
+ * @param override flag that defines if the value computed here
330
+ * overrides the one already in the input context if that is the
331
+ * case. I.e. decides if this is a default value or a local
332
+ * value. xsl:variable and xsl:with-param override; xsl:param doesn't.
333
+ */
334
+ Xslt.prototype.xsltVariable = function (input, template, override) {
335
+ var name = (0, dom_1.xmlGetAttribute)(template, 'name');
336
+ var select = (0, dom_1.xmlGetAttribute)(template, 'select');
337
+ var value;
338
+ if (template.childNodes.length > 0) {
339
+ var root = (0, dom_1.domCreateDocumentFragment)(template.ownerDocument);
340
+ this.xsltChildNodes(input, template, root);
341
+ value = new values_1.NodeSetValue([root]);
342
+ }
343
+ else if (select) {
344
+ value = this.xPath.xPathEval(select, input);
345
+ }
346
+ else {
347
+ value = new values_1.StringValue('');
348
+ }
349
+ if (override || !input.getVariable(name)) {
350
+ input.setVariable(name, value);
351
+ }
352
+ };
353
+ // Implements xsl:chose and its child nodes xsl:when and
354
+ // xsl:otherwise.
355
+ Xslt.prototype.xsltChoose = function (input, template, output) {
356
+ for (var _i = 0, _a = template.childNodes; _i < _a.length; _i++) {
357
+ var childNode = _a[_i];
358
+ if (childNode.nodeType !== constants_1.DOM_ELEMENT_NODE) {
359
+ continue;
360
+ }
361
+ if (this.isXsltElement(childNode, 'when')) {
362
+ var test_2 = (0, dom_1.xmlGetAttribute)(childNode, 'test');
363
+ if (this.xPath.xPathEval(test_2, input).booleanValue()) {
364
+ this.xsltChildNodes(input, childNode, output);
365
+ break;
366
+ }
367
+ }
368
+ else if (this.isXsltElement(childNode, 'otherwise')) {
369
+ this.xsltChildNodes(input, childNode, output);
370
+ break;
371
+ }
372
+ }
373
+ };
374
+ /**
375
+ * Implements `xsl:for-each`.
376
+ * @param context TODO
377
+ * @param template TODO
378
+ * @param output TODO
379
+ */
380
+ Xslt.prototype.xsltForEach = function (context, template, output) {
381
+ var select = (0, dom_1.xmlGetAttribute)(template, 'select');
382
+ var nodes = this.xPath.xPathEval(select, context).nodeSetValue();
383
+ var sortContext = context.clone(nodes, 0);
384
+ this.xsltSort(sortContext, template);
385
+ var nodesWithParent = sortContext.nodelist.filter(function (n) { return n.parentNode !== null && n.parentNode !== undefined; });
386
+ if (nodesWithParent.length <= 0) {
387
+ throw new Error('Nodes with no parents defined.');
388
+ }
389
+ var parent = nodesWithParent[0].parentNode;
390
+ parent.childNodes = sortContext.nodelist;
391
+ for (var i = 0; i < sortContext.contextSize(); ++i) {
392
+ this.xsltChildNodes(sortContext.clone(sortContext.nodelist, i), template, output);
393
+ }
394
+ // TODO: group nodes by parent node.
395
+ // const nodeGroups = this.groupBy(nodes, 'parentNode');
396
+ /* for (let [group, _nodes] of Object.entries(nodeGroups)) {
397
+ const sortContext = context.clone(_nodes, 0);
398
+ this.xsltSort(sortContext, template);
399
+
400
+ for (let i = 0; i < sortContext.contextSize(); ++i) {
401
+ this.xsltChildNodes(sortContext.clone(sortContext.nodelist, i), template, output);
402
+ }
403
+ } */
404
+ };
405
+ Xslt.prototype.groupBy = function (xs, key) {
406
+ return xs.reduce(function (rv, x) {
407
+ (rv[x[key]] = rv[x[key]] || []).push(x);
408
+ return rv;
409
+ }, {});
410
+ };
411
+ /**
412
+ * Traverses the template node tree. Calls the main processing
413
+ * function with the current input context for every child node of the
414
+ * current template node.
415
+ * @param context Normally the Expression Context.
416
+ * @param template The XSL-T definition.
417
+ * @param output The XML output.
418
+ */
419
+ Xslt.prototype.xsltChildNodes = function (context, template, output) {
420
+ // Clone input context to keep variables declared here local to the
421
+ // siblings of the children.
422
+ var contextClone = context.clone();
423
+ for (var i = 0; i < template.childNodes.length; ++i) {
424
+ this.xsltProcessContext(contextClone, template.childNodes[i], output);
425
+ }
426
+ };
427
+ /**
428
+ * Passes template text to the output. The current template node does
429
+ * not specify an XSL-T operation and therefore is appended to the
430
+ * output with all its attributes. Then continues traversing the
431
+ * template node tree.
432
+ * @param context The Expression Context.
433
+ * @param template The XSLT stylesheet or transformation.
434
+ * @param output The output.
435
+ * @param outputDocument The output document, if the case.
436
+ */
437
+ Xslt.prototype.xsltPassThrough = function (context, template, output, outputDocument) {
438
+ if (template.nodeType == constants_1.DOM_TEXT_NODE) {
439
+ if (this.xsltPassText(template)) {
440
+ var textNodeList = context.nodelist[context.position].transformedChildNodes.filter(function (n) { return n.nodeType === constants_1.DOM_TEXT_NODE; });
441
+ if (textNodeList.length > 0) {
442
+ var node = textNodeList[0];
443
+ node.transformedNodeValue = template.nodeValue;
444
+ }
445
+ else {
446
+ var node = (0, dom_1.domCreateTextNode)(outputDocument, template.nodeValue);
447
+ (0, dom_1.domAppendTransformedChild)(context.nodelist[context.position], node);
448
+ }
449
+ }
450
+ }
451
+ else if (template.nodeType == constants_1.DOM_ELEMENT_NODE) {
452
+ var node = void 0;
453
+ if (context.nodelist[context.position].nodeName === '#document') {
454
+ node = context.nodelist[context.position].firstChild;
455
+ }
456
+ else {
457
+ node = context.nodelist[context.position];
458
+ }
459
+ node.transformedNodeName = template.nodeName;
460
+ node.transformedLocalName = template.localName;
461
+ for (var _i = 0, _a = template.attributes.filter(function (a) { return a; }); _i < _a.length; _i++) {
462
+ var attribute = _a[_i];
463
+ var name_2 = attribute.nodeName;
464
+ var value = this.xsltAttributeValue(attribute.nodeValue, context);
465
+ (0, dom_1.domSetTransformedAttribute)(node, name_2, value);
466
+ }
467
+ this.xsltChildNodes(context, template, node);
468
+ }
469
+ else {
470
+ // This applies also to the DOCUMENT_NODE of the XSL stylesheet,
471
+ // so we don't have to treat it specially.
472
+ this.xsltChildNodes(context, template, output);
473
+ }
474
+ };
475
+ /**
476
+ * Determines if a text node in the XSLT template document is to be
477
+ * stripped according to XSLT whitespace stripping rules.
478
+ * @see [XSLT], section 3.4.
479
+ * @param template The XSLT template.
480
+ * @returns TODO
481
+ * @todo Whitespace stripping on the input document is
482
+ * currently not implemented.
483
+ */
484
+ Xslt.prototype.xsltPassText = function (template) {
485
+ if (!template.nodeValue.match(/^\s*$/)) {
486
+ return true;
487
+ }
488
+ var element = template.parentNode;
489
+ if (this.isXsltElement(element, 'text')) {
490
+ return true;
491
+ }
492
+ while (element && element.nodeType == constants_1.DOM_ELEMENT_NODE) {
493
+ var xmlspace = (0, dom_1.domGetAttributeValue)(element, 'xml:space');
494
+ if (xmlspace) {
495
+ if (xmlspace == 'default') {
496
+ return false;
497
+ }
498
+ if (xmlspace == 'preserve') {
499
+ return true;
500
+ }
501
+ }
502
+ element = element.parentNode;
503
+ }
504
+ return false;
505
+ };
506
+ /**
507
+ * Evaluates an XSL-T attribute value template. Attribute value
508
+ * templates are attributes on XSL-T elements that contain XPath
509
+ * expressions in braces {}. The XSL-T expressions are evaluated in
510
+ * the current input context.
511
+ * @param value TODO
512
+ * @param context TODO
513
+ * @returns TODO
514
+ */
515
+ Xslt.prototype.xsltAttributeValue = function (value, context) {
516
+ var parts = value.split('{');
517
+ if (parts.length == 1) {
518
+ return value;
519
+ }
520
+ var ret = '';
521
+ for (var i = 0; i < parts.length; ++i) {
522
+ var rp = parts[i].split('}');
523
+ if (rp.length != 2) {
524
+ // first literal part of the value
525
+ ret += parts[i];
526
+ continue;
527
+ }
528
+ var val = this.xPath.xPathEval(rp[0], context).stringValue();
529
+ ret += val + rp[1];
530
+ }
531
+ return ret;
532
+ };
533
+ /**
534
+ * Implements xsl:copy-of for node-set values of the select
535
+ * expression. Recurses down the source node tree, which is part of
536
+ * the input document.
537
+ * @param {XNode} dst the node being copied to, part of output document
538
+ * @param {XNode} src the node being copied, part in input document
539
+ * @param {XDocument} dstDocument dstDocument
540
+ */
541
+ Xslt.prototype.xsltCopyOf = function (dst, src, dstDocument) {
542
+ if (src.nodeType == constants_1.DOM_DOCUMENT_FRAGMENT_NODE || src.nodeType == constants_1.DOM_DOCUMENT_NODE) {
543
+ for (var i = 0; i < src.childNodes.length; ++i) {
544
+ this.xsltCopyOf(dst, src.childNodes[i], dstDocument);
545
+ }
546
+ }
547
+ else {
548
+ var node = this.xsltCopy(dst, src, dstDocument);
549
+ if (node) {
550
+ // This was an element node -- recurse to attributes and
551
+ // children.
552
+ for (var i = 0; i < src.attributes.length; ++i) {
553
+ this.xsltCopyOf(node, src.attributes[i], dstDocument);
554
+ }
555
+ for (var i = 0; i < src.childNodes.length; ++i) {
556
+ this.xsltCopyOf(node, src.childNodes[i], dstDocument);
557
+ }
558
+ }
559
+ }
560
+ };
561
+ /**
562
+ * Evaluates an XPath expression in the current input context as a
563
+ * match.
564
+ * @see [XSLT] section 5.2, paragraph 1
565
+ * @param match TODO
566
+ * @param context TODO
567
+ * @returns TODO
568
+ */
569
+ Xslt.prototype.xsltMatch = function (match, context) {
570
+ var expr = this.xPath.xPathParse(match);
571
+ if (expr.steps.length <= 0) {
572
+ throw new Error('Error resolving XSLT match: Location Expression should have steps.');
573
+ }
574
+ var firstStep = expr.steps[0];
575
+ // Shortcut for the most common case.
576
+ if (expr.steps &&
577
+ !expr.absolute &&
578
+ expr.steps.length == 1 &&
579
+ firstStep.axis == 'child' &&
580
+ firstStep.predicate.length === 0) {
581
+ return firstStep.nodetest.evaluate(context).booleanValue();
582
+ }
583
+ if (expr.absolute && firstStep.axis !== 'self') {
584
+ // TODO: `xPathCollectDescendants()`?
585
+ var levels = match.split('/');
586
+ if (levels.length > 1) {
587
+ return this.absoluteXsltMatch(levels, expr, context);
588
+ }
589
+ }
590
+ return this.relativeXsltMatch(expr, context);
591
+ };
592
+ /**
593
+ * Sets parameters defined by xsl:with-param child nodes of the
594
+ * current template node, in the current input context. This happens
595
+ * before the operation specified by the current template node is
596
+ * executed.
597
+ * @param input TODO
598
+ * @param template TODO
599
+ */
600
+ Xslt.prototype.xsltWithParam = function (input, template) {
601
+ for (var _i = 0, _a = template.childNodes; _i < _a.length; _i++) {
602
+ var c = _a[_i];
603
+ if (c.nodeType === constants_1.DOM_ELEMENT_NODE && this.isXsltElement(c, 'with-param')) {
604
+ this.xsltVariable(input, c, true);
605
+ }
606
+ }
607
+ };
608
+ Xslt.prototype.absoluteXsltMatch = function (levels, expr, context) {
609
+ var result = expr.evaluate(context.clone([context.nodelist[context.position]], 0)).nodeSetValue();
610
+ if (result.length > 0) {
611
+ context.nodelist = result;
612
+ return true;
613
+ }
614
+ return false;
615
+ };
616
+ Xslt.prototype.relativeXsltMatch = function (expr, context) {
617
+ var node = context.nodelist[context.position];
618
+ while (node) {
619
+ var result = expr.evaluate(context.clone([node], 0)).nodeSetValue();
620
+ for (var i = 0; i < result.length; ++i) {
621
+ if (result[i] == context.nodelist[context.position]) {
622
+ /* if (context.node.nodeName === "#document") {
623
+ context.node = con
624
+ } */
625
+ return true;
626
+ }
627
+ }
628
+ node = node.parentNode;
629
+ }
630
+ return false;
631
+ };
632
+ // Test if the given element is an XSLT element, optionally the one with the given name
633
+ Xslt.prototype.isXsltElement = function (element, opt_wantedName) {
634
+ if (opt_wantedName && element.localName != opt_wantedName)
635
+ return false;
636
+ if (element.namespaceURI)
637
+ return element.namespaceURI === 'http://www.w3.org/1999/XSL/Transform';
638
+ return element.prefix === 'xsl'; // backwards compatibility with earlier versions of xslt-processor
639
+ };
640
+ return Xslt;
641
+ }());
642
+ exports.Xslt = Xslt;
643
+ //# sourceMappingURL=xslt.js.map