2Copyright 2020-2021 Intel Corporation
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
16@description Intel AMT XML parsing module
17@author Ylian Saint-Hilaire
23/*jshint strict:false */
25/*jshint esversion: 6 */
28// Parse XML and return JSON
29module.exports.ParseWsman = function (xml) {
31 if (!xml.childNodes) xml = _turnToXml(xml);
32 var r = { Header: {} }, header = xml.getElementsByTagName("Header")[0], t;
33 if (!header) header = xml.getElementsByTagName("a:Header")[0];
34 if (!header) return null;
35 for (var i = 0; i < header.childNodes.length; i++) {
36 var child = header.childNodes[i];
37 r.Header[child.localName] = child.textContent;
39 var body = xml.getElementsByTagName("Body")[0];
40 if (!body) body = xml.getElementsByTagName("a:Body")[0];
41 if (!body) return null;
42 if (body.childNodes.length > 0) {
43 t = body.childNodes[0].localName;
44 var x = t.indexOf('_OUTPUT');
45 if ((x != -1) && (x == (t.length - 7))) { t = t.substring(0, t.length - 7); }
46 r.Header['Method'] = t;
47 r.Body = _ParseWsmanRec(body.childNodes[0]);
51 console.log("Unable to parse XML: " + xml);
57function _ParseWsmanRec(node) {
59 for (var i = 0; i < node.childNodes.length; i++) {
60 var child = node.childNodes[i];
61 if ((child.childElementCount == null) || (child.childElementCount == 0)) { data = child.textContent; } else { data = _ParseWsmanRec(child); }
62 if (data == 'true') data = true; // Convert 'true' into true
63 if (data == 'false') data = false; // Convert 'false' into false
64 if ((parseInt(data) + '') === data) data = parseInt(data); // Convert integers
67 if ((child.attributes != null) && (child.attributes.length > 0)) {
68 childObj = { 'Value': data };
69 for (var j = 0; j < child.attributes.length; j++) {
70 childObj['@' + child.attributes[j].name] = child.attributes[j].value;
74 if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); }
75 else if (r[child.localName] == null) { r[child.localName] = childObj; }
76 else { r[child.localName] = [r[child.localName], childObj]; }
81function _PutObjToBodyXml(resuri, putObj) {
82 if (!resuri || putObj == null) return '';
83 var objname = obj.GetNameFromUrl(resuri);
84 var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
86 for (var prop in putObj) {
87 if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
88 if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
89 if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
90 result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
91 var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
92 if (Array.isArray(selectorArray)) {
93 for (var i = 0; i < selectorArray.length; i++) {
94 result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
98 result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
100 result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
103 if (Array.isArray(putObj[prop])) {
104 for (var i = 0; i < putObj[prop].length; i++) {
105 result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
108 result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
113 result += '</r:' + objname + '>';
117// This is a drop-in replacement to _turnToXml() that works without xml parser dependency.
118try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : null); } }); } catch (ex) { }
119function _treeBuilder() {
121 this.push = function (element) { this.tree.push(element); };
122 this.pop = function () { var element = this.tree.pop(); if (this.tree.length > 0) { var x = this.tree.peek(); x.childNodes.push(element); x.childElementCount = x.childNodes.length; } return (element); };
123 this.peek = function () { return (this.tree.peek()); }
124 this.addNamespace = function (prefix, namespace) { this.tree.peek().nsTable[prefix] = namespace; if (this.tree.peek().attributes.length > 0) { for (var i = 0; i < this.tree.peek().attributes; ++i) { var a = this.tree.peek().attributes[i]; if (prefix == '*' && a.name == a.localName) { a.namespace = namespace; } else if (prefix != '*' && a.name != a.localName) { var pfx = a.name.split(':')[0]; if (pfx == prefix) { a.namespace = namespace; } } } } }
125 this.getNamespace = function (prefix) { for (var i = this.tree.length - 1; i >= 0; --i) { if (this.tree[i].nsTable[prefix] != null) { return (this.tree[i].nsTable[prefix]); } } return null; }
127function _turnToXml(text) { if (text == null) return null; return ({ childNodes: [_turnToXmlRec(text)], getElementsByTagName: _getElementsByTagName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS }); }
128function _getElementsByTagNameNS(ns, name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name && (node.namespace == ns || ns == '*')) { ret.push(node); } }); return ret; }
129function _getElementsByTagName(name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name) { ret.push(node); } }); return ret; }
130function _getChildElementsByTagName(name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name) { ret.push(this.childNodes[node]); } } } return (ret); }
131function _getChildElementsByTagNameNS(ns, name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name && (ns == '*' || this.childNodes[node].namespace == ns)) { ret.push(this.childNodes[node]); } } } return (ret); }
132function _xmlTraverseAllRec(nodes, func) { for (var i in nodes) { func(nodes[i]); if (nodes[i].childNodes) { _xmlTraverseAllRec(nodes[i].childNodes, func); } } }
133function _turnToXmlRec(text) {
134 var elementStack = new _treeBuilder(), lastElement = null, x1 = text.split('<'), ret = [], element = null, currentElementName = null;
136 var x2 = x1[i].split('>'), x3 = x2[0].split(' '), elementName = x3[0];
137 if ((elementName.length > 0) && (elementName[0] != '?')) {
138 if (elementName[0] != '/') {
139 var attributes = [], localName, localname2 = elementName.split(' ')[0].split(':'), localName = (localname2.length > 1) ? localname2[1] : localname2[0];
140 Object.defineProperty(attributes, "get",
143 if (arguments.length == 1) {
144 for (var a in this) { if (this[a].name == arguments[0]) { return (this[a]); } }
146 else if (arguments.length == 2) {
147 for (var a in this) { if (this[a].name == arguments[1] && (arguments[0] == '*' || this[a].namespace == arguments[0])) { return (this[a]); } }
150 throw ('attributes.get(): Invalid number of parameters');
154 elementStack.push({ name: elementName, localName: localName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS, getChildElementsByTagNameNS: _getChildElementsByTagNameNS, attributes: attributes, childNodes: [], nsTable: {} });
160 // This is an empty Element
161 elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
162 elementStack.peek().textContent = '';
163 lastElement = elementStack.pop();
167 var k = x3[j].indexOf('=');
169 var attrName = x3[j].substring(0, k);
170 var attrValue = x3[j].substring(k + 2, x3[j].length - 1);
171 var attrNS = elementStack.getNamespace('*');
173 if (attrName == 'xmlns') {
174 elementStack.addNamespace('*', attrValue);
176 } else if (attrName.startsWith('xmlns:')) {
177 elementStack.addNamespace(attrName.substring(6), attrValue);
179 var ax = attrName.split(':');
180 if (ax.length == 2) { attrName = ax[1]; attrNS = elementStack.getNamespace(ax[0]); }
182 var x = { name: attrName, value: attrValue }
183 if (attrNS != null) x.namespace = attrNS;
184 elementStack.peek().attributes.push(x);
187 if (skip) { continue; }
189 elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
190 if (x2[1]) { elementStack.peek().textContent = x2[1]; }
191 } else { lastElement = elementStack.pop(); }