Sorry its taking so long, don't have the hours I used to to pour into things like this. But to show progress (and maybe you know enough about COMs to make use of it) here's the jscript, exposed methods are json2yaml and xml2yaml

Code
(function () {
    
    // Helper Function: returns the subject's cast type
    function getType(subject) {
        return Object.prototype.toString.call(subject).match(/^\[object (\S+)\]$/)[1].toLowerCase();
    }
    
    // Helper Function: returns true if the subject has the specified property and it is not part of its inheritence chain
    function has(subject, key) {
        return Object.prototype.hasOwnProperty.call(subject, key);
    }
    
    // Helper Function: removes EOL characters from text
    function trim(text) {
        return text.replace(/[\r\n]+$/g, '');
    }

    // Helper Function: Escapes text to be YAML compliant
    function yamlText(text) {
        
        // empty text
        if (text === '') {
            return '""';
        }
        
        // text contains characters that require quoting
        if (/(?:^[!&*-?#|>@`"' ])|[{}\[\]\(\),:\t\r\n\\\/]|(?: $)/g.test(text)) {
            return '"' + text.replace(
                /[\\"\u0000-\u001F\u2028\u2029]/g,
                function (chr) {
                    return {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'}[chr] || '\\u' + (chr.charCodeAt(0) + 0x10000).toString(16).substr(1);
                }
            ) + '"';  
        }
        
        // text can be left as-is
        return text;
    }

    // Helper Function: Formats the specified collection item to be YAML compliant
    function yamlItem(data, indent) {
        
        // text
        if (typeof data == 'string') {
            return ' ' + yamltext(data);
        }
        
        // null, boolean, numbers
        if (data === null || data === !!data || isFinite(data)) {
            return ' ' + data;
        }
        
        // collections
        data = yaml(data, indent + 2);
        if (data != undefined) {
            if (data === '[]' || data === '{}') {
                return ' ' + data;
            }
            return '\n' + data;
        }
    }

    // YAML conversion entry point
    function yaml(data, indent) {
        var type = getType(data),
            index,
            value,
            hasChild,
            result = '';

        // no data, return
        if (data === undefined) {
            return;
        }
        
        // text
        if (type == 'string') {
            return yamlText(data);
        }
        
        // null, boolean, numbers
        if (data == null || type == 'boolean' || isFinite(data)) {
            return '' + data;
        }
        
        // collections
        if (type == 'array' || type == 'object') {
            
            // loop over each item in collection
            for (index in data) {
                if (has(data, index)) {
                    
                    // convert to YAML item and append to result
                    value = yamlItem(data[index], indent);
                    if (value != null) {
                        hasChild = true;
                        result += Array(indent + 1).join(' ') + (type == 'array' ? '-' : yamlText(index) + ':') + trim(value) + '\n';
                    }
                }
            }
            
            // return result
            return trim(hasChild ? result : type == 'array' ? '[]' : '{}') + '\n';
        }
    }

    // Helper Function: Recursively walks an XML document, processing it into a proper JS collection
    function xmlWalk(node, parent) {
        var result = {
                attributes: {},
                children: {},
                value: node.text
            },
            index,
            attr,
            child;

        // loop over all attributes and add them to the result's attributes collection
        for (index = 0; index < node.attributes.length; index += 1) {
            attr = node.attributes[index];
            result.attributes[attr.nodeName] = attr.text || true;
        }
        
        // loop over all children and add them to the result's attributes collection
        for (index = 0; index < node.childNodes.length; index += 1) {
            child = node.childNodes[index];
            if (child.nodeType === 1) {
                xmlWalk(child, result.children);
            }
        }
        
        // if theres no attributes and no children nodes, store this node's value as being its text
        if (node.childNodes.length === 0 && node.attributes.length === 0) {
            result = node.text || true;
        }

        // store the node based on the parent:
        // Parent does not have entry for the node name: add entry with result as its value
        if (!has(parent, node.nodeName)) {
            parent[node.nodeName] = result;

        // parent's entry for node name is an array: append result
        } else if (getType(parent[node.nodeName]) == 'array') {
            parent[node.nodeName].push(result);

        // parent's entry for node name is not an array: convert to array and append result
        } else {
            parent[node.nodeName] = [parent[node.nodeName], result];
        }
    }
    
    // Exposed Function: Converts an XML string into YAML
    xml2yaml = function (data) {
        
        // initial XML parser
        var xml = new ActiveXObject("Msxml2.DOMDocument.6.0");
        xml.async = false;
        
        // load xml into parser
        try {
            var loaded = xml.loadXML(data);
        } catch (e) {
            throw new Error('INVALID_XML');
        }
        if (!loaded || xml.documentElement == null) {
            throw new Error('INVALID_XML');
        }
        
        // walk the XML, converting it to a more managable JS object
        xmlWalk(xml.documentElement, data = {});
        
        // convert the JS object to YAML
        return yaml(data, 0);
    };
    
    // Exposed Function: Converts a JSON string into a YAML
    json2yaml = function (data) {
        
        // parse JSON into JS object
        data = String(data).replace(/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, function(chr) {
            return '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);
        });
        if (!/^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
            throw new Error("INVALID_JSON");
        }
        try {
            data = eval('(' + data + ')');
        } catch (e) {
            throw new Error("INVALID_JSON");
        }
        
        // convert JS object to YAML
        return yaml(data, 0);
    };
}());

Last edited by FroggieDaFrog; 09/08/19 10:06 AM.