aft-web-services
Version:
Automated Functional Testing (AFT) module for testing web services over HTTP and HTTPS
186 lines • 6.67 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.XML = void 0;
const xmldoc_1 = require("xmldoc");
class XML {
/**
* converts a passed in XML object into a Javascript object
*
* XML to object deserialisation will use the following rules:
* - element names become property names
* - attributes become properties preceeded by an `@` symbol inside the element object
* - element text content is rendered in a special property named `keyValue`
*
* *Ex:*
* ```xml
* <html>
* <image src="./foo/bar/baz.jpg" />
* <hr />
* <span style="color:#808080" class="hidden rounded">
* This is coloured
* </span>
* </html>
* ```
* will become:
* ```json
* {
* "html": {
* "image": {
* "@src": "./foo/bar/baz.jpg",
* },
* "hr": {},
* "span": {
* "@style": "color:#808080",
* "@class": "hidden rounded",
* "keyValue": "This is coloured"
* }
* }
* }
* ```
* @param oXMLParent an XML Document, Element or DocumentFragment to be converted
* into a Javascript Object
* @returns a Javascript Object representation of the passed in XML object
*/
static toObject(oXMLParent) {
const vResult = {};
let nLength = 0;
let sCollectedTxt = "";
let oXMLParentElement = oXMLParent;
if ((oXMLParentElement === null || oXMLParentElement === void 0 ? void 0 : oXMLParentElement.hasAttributes) && (oXMLParentElement === null || oXMLParentElement === void 0 ? void 0 : oXMLParentElement.attributes) && (oXMLParentElement === null || oXMLParentElement === void 0 ? void 0 : oXMLParentElement.hasAttributes())) {
for (nLength; nLength < oXMLParentElement.attributes.length; nLength++) {
const oAttrib = oXMLParentElement.attributes.item(nLength);
vResult["@" + oAttrib.name.toLowerCase()] = XML._parseText(oAttrib.value.trim());
}
}
if (oXMLParent.hasChildNodes()) {
for (let oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
oNode = oXMLParent.childNodes.item(nItem);
if (oNode.nodeType === 4) { /* nodeType is "CDATASection" (4) */
sCollectedTxt += oNode.nodeValue;
}
else if (oNode.nodeType === 3) { /* nodeType is "Text" (3) */
sCollectedTxt += oNode.nodeValue.trim();
}
else if (oNode.nodeType === 1 && !oNode.prefix) { /* nodeType is "Element" (1) */
sProp = oNode.nodeName.toLowerCase();
vContent = XML.toObject(oNode);
if (vResult.hasOwnProperty(sProp)) {
if (vResult[sProp].constructor !== Array) {
vResult[sProp] = [vResult[sProp]];
}
vResult[sProp].push(vContent);
}
else {
vResult[sProp] = vContent;
nLength++;
}
}
}
}
if (sCollectedTxt) {
vResult.keyValue = XML._parseText(sCollectedTxt);
}
return vResult;
}
/**
* converts the passed in XML string into a Javascript object
*
* XML to object deserialisation will use the following rules:
* - element names become property names
* - attributes become properties preceeded by an `@` symbol inside the element object
* - element text content is rendered in a special property named `keyValue`
*
* *Ex:*
* ```xml
* <html>
* <image src="./foo/bar/baz.jpg" />
* <hr />
* <span style="color:#808080" class="hidden rounded">
* This is coloured
* </span>
* </html>
* ```
* will become:
* ```json
* {
* "html": {
* "image": {
* "@src": "./foo/bar/baz.jpg",
* },
* "hr": {},
* "span": {
* "@style": "color:#808080",
* "@class": "hidden rounded",
* "keyValue": "This is coloured"
* }
* }
* }
* ```
* @param xml an XML string to be converted into a Javascript object
* @returns a Javascript object representing the passed in XML string
*/
static fromString(xml) {
const xmlDoc = new xmldoc_1.XmlDocument(xml);
const obj = {};
XML._fromXmlNode(xmlDoc, obj);
return obj;
}
static _parseText(sValue) {
if (/^\s*$/.test(sValue)) {
return null;
}
if (/^(?:true|false)$/i.test(sValue)) {
return sValue.toLowerCase() === "true";
}
if (isFinite(sValue)) {
return parseFloat(sValue);
}
if (isFinite(Date.parse(sValue))) {
return new Date(sValue);
}
return sValue;
}
static _fromXmlNode(xml, current) {
switch (xml.type) {
case 'element':
XML._fromElement(xml, current);
break;
case 'cdata':
current['keyValue'] = XML._parseText(xml.cdata);
break;
case 'text':
current['keyValue'] = XML._parseText(xml.text);
break;
case 'comment':
default:
/* ignore */
break;
}
}
static _fromElement(element, parent) {
var _a;
if (element.name) {
const n = element.name;
parent[n] = {};
if (element.attr) {
const attributeKeys = Object.keys(element.attr);
if (attributeKeys.length) {
for (const aKey of attributeKeys) {
parent[n][`@${aKey}`] = XML._parseText(element.attr[aKey].trim());
}
}
}
if (element.val) {
const v = element.val;
parent[n]['keyValue'] = XML._parseText(v);
}
if ((_a = element.children) === null || _a === void 0 ? void 0 : _a.length) {
for (const child of element.children) {
XML._fromXmlNode(child, parent[n]);
}
}
}
}
}
exports.XML = XML;
//# sourceMappingURL=xml.js.map