четверг, 7 июля 2016 г.

Parse XML to JSON

var xml = '<?xml version="1.0" encoding="UTF-8"?>'
            + '<catalog>'
            + '<book id="bk101">'
            + '<author>Gambardella, Matthew</author>'
            + '<title>XML Developer\'s Guide</title>'
            + '<genre>Computer</genre>'
            + '<price>44.95</price>'
            + '<publish_date>2000-10-01</publish_date>'
            + '<description>An in-depth look at creating applications with XML.</description>'
            + '</book>'
            + '</catalog>';

function parseXML (data) {
    var xml, tmp;
    if (!data || typeof data !== "string") {
        return null;
    }
    try {
        if (window.DOMParser) { // Standard
            tmp = new DOMParser();
            xml = tmp.parseFromString(data, "text/xml");
        } else { // IE
            xml = new ActiveXObject("Microsoft.XMLDOM");
            xml.async = "false";
            xml.loadXML(data);
        }
    } catch(e) {
        xml = undefined;
    }
    if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) {
        throw new Error("Invalid XML: " + data);
    }
    return xml;
}

// Changes XML to JSON
function xmlToJson(xml) {
   
    // Create the return object
    var obj = {};

    if (xml.nodeType == 1) { // element
        // do attributes
        if (xml.attributes.length > 0) {
        obj["@attributes"] = {};
            for (var j = 0; j < xml.attributes.length; j++) {
                var attribute = xml.attributes.item(j);
                obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
            }
        }
    } else if (xml.nodeType == 3) { // text
        obj = xml.nodeValue;
    }

    // do children
    if (xml.hasChildNodes()) {
        for(var i = 0; i < xml.childNodes.length; i++) {
            var item = xml.childNodes.item(i);
            var nodeName = item.nodeName;
            if (typeof(obj[nodeName]) == "undefined") {
                obj[nodeName] = xmlToJson(item);
            } else {
                if (typeof(obj[nodeName].push) == "undefined") {
                    var old = obj[nodeName];
                    obj[nodeName] = [];
                    obj[nodeName].push(old);
                }
                obj[nodeName].push(xmlToJson(item));
            }
        }
    }
    return obj;
}

function convertObjectToHtmlText (obj, options) {
    var indentString = '&nbsp;&nbsp;&nbsp;&nbsp;'
       , newLine = '<br />'
       , newLineJoin = ',' + newLine;
    if (options && options.rawHTML) {
        indentString = '    '; // 4 пробела
        newLine = '\n';
        newLineJoin = ',' + newLine;
    }
    // Функция определения типа объекта
    function objectType (obj) {
        var types = {
              'null': 'null'
            , 'undefined': 'undefined'
            , 'number': 'number'
            , 'boolean': 'boolean'
            , 'string': 'string'
            , '[object Function]': 'function'
            , '[object RegExp]': 'regexp'
            , '[object Array]': 'array'
            , '[object Date]': 'date'
            , '[object Error]': 'error'
        };
        return types[typeof obj] || types[Object.prototype.toString.call(obj)] || (obj ? 'object' : 'null');
    }
    // Функция определения числа элементов в объекте
    function objectSize (obj) {
        var size = 0
            , key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {size++;}
        }
        return size;
    }
    // Привести элемент к нужному формату
    function formatElement (element, indent, indentFromArray) {
        indentFromArray = indentFromArray || '';
        switch (objectType(element)) {
            case 'null': return indentFromArray + 'null';
            case 'undefined': return indentFromArray + 'undefined';
            case 'number': return indentFromArray + element;
            case 'boolean': return indentFromArray + (element ? 'true' : 'false');
            case 'string': if (options && options.rawHTML) {
                                    return indentFromArray + '"'
                                                                         + element
                                                                         + '"';
                                } else {
                                    return indentFromArray + '&quot;'
                                                                         + element.replace(/&/g, '&amp;')
                                                                                        .replace(/</g, '&lt;')
                                                                                        .replace(/>/g, '&gt;')
                                                                                        .replace(/"/, '&quot;')
                                                                                        .replace(/'/g, '&#039;')
                                                                         + '&quot;';
                                }
            case 'array': return indentFromArray + (element.length > 0 ? '[' + newLine + formatArray(element, indent) + indent + ']' : '[]');
            case 'object': return indentFromArray + (objectSize(element) > 0 ? '{' + newLine + formatObject(element, indent) + indent + '}' : '{}');
            default: return indentFromArray + element.toString();
        }
    }
    // Привести массив к нужному формату
    function formatArray (array, indent) {
        var index
            , length = array.length
            , value = [];
        indent += indentString;
        for (index = 0; index < length; index += 1) {
            value.push(formatElement(array[index], indent, indent));
        }
        return value.join(newLineJoin) + newLine;
    }
    // Привести объект к нужному формату
    function formatObject (object, indent) {
        var value = []
            , property;
        indent += indentString;
        for (property in object) {
            if (object.hasOwnProperty(property)) {
                if (options && options.rawHTML) {
                    value.push(indent + '"' + property + '": ' + formatElement(object[property], indent));
                } else {
                    value.push(indent + '&quot;' + property + '&quot;: ' + formatElement(object[property], indent));
                }
            }
        }
        return value.join(newLineJoin) + newLine;
    }
    if (typeof obj === 'object') {return formatElement(obj, '');
    } else {throw new Error ('No javascript object has been provided to function convertObjectToHtmlText (obj) {...}');
    }
}

console.log(JSON.stringify(xmlToJson(parseXML(xml))));

console.log(convertObjectToHtmlText (xmlToJson(parseXML(xml)), {rawHTML: true}));

1 комментарий:

  1. function xmlStringToJSON(xml, primaryTag = 'resposta') {
    if (!xml) return {};
    const regex = new RegExp(`<${primaryTag}.*[^>]>((?:.*\n)*(?=<\/${primaryTag}>))`, 'gmi');
    xml = regex.exec(xml)[1].replace(/&/g, "&")
    .replace(/</g, "<")
    .replace(/>/g, ">")
    .replace(/"/g, "\"")
    .replace(/'/g, "'")
    .replace(/\t/g, '')
    if (!xml) return {};
    if (xml.indexOf(' -1) xml = xml
    .replace(xml.slice(xml.indexOf('') + 2), '');
    xml = xml.split('\n').filter(itm => !!itm.trim());
    return (function recursiveParse(lines, currentLine = 0, object = {}, parent = null) {
    if (currentLine === lines.length) return object;
    const line = lines[currentLine],
    openTag = line.match(/<([^\/\s>]+)(\s|>)+/),
    closeTag = line.match(/<\/([^\s>]+)(\s|>)+/),
    tagContent = line.match(/(?<=>)(.+)(?=<\/)/);
    currentLine++;
    if (!tagContent && openTag && !closeTag)
    object[openTag[1]] = recursiveParse(lines, currentLine, {}, object);
    else if (tagContent && openTag && closeTag) {
    object[openTag[1]] = tagContent[0];
    recursiveParse(lines, currentLine, object, parent);
    } else if (!tagContent && !openTag && closeTag)
    recursiveParse(lines, currentLine, parent);
    return object;
    })(xml);
    }

    ОтветитьУдалить