summaryrefslogtreecommitdiff
path: root/lib/xml/reader.js
blob: 279732384f035b450a46c7fb02cf46397ac3574d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
var promises = require("../promises");
var _ = require("underscore");

var xmldom = require("./xmldom");
var nodes = require("./nodes");
var Element = nodes.Element;

exports.readString = readString;

var Node = xmldom.Node;

function readString(xmlString, namespaceMap) {
    namespaceMap = namespaceMap || {};

    try {
        var document = xmldom.parseFromString(xmlString, "text/xml");
    } catch (error) {
        return promises.reject(error);
    }

    if (document.documentElement.tagName === "parsererror") {
        return promises.resolve(new Error(document.documentElement.textContent));
    }

    function convertNode(node) {
        switch (node.nodeType) {
        case Node.ELEMENT_NODE:
            return convertElement(node);
        case Node.TEXT_NODE:
            return nodes.text(node.nodeValue);
        }
    }

    function convertElement(element) {
        var convertedName = convertName(element);

        var convertedChildren = [];
        _.forEach(element.childNodes, function(childNode) {
            var convertedNode = convertNode(childNode);
            if (convertedNode) {
                convertedChildren.push(convertedNode);
            }
        });

        var convertedAttributes = Object.create(null);
        _.forEach(element.attributes, function(attribute) {
            convertedAttributes[convertName(attribute)] = attribute.value;
        });

        return new Element(convertedName, convertedAttributes, convertedChildren);
    }

    function convertName(node) {
        if (node.namespaceURI) {
            var mappedPrefix = namespaceMap[node.namespaceURI];
            var prefix;
            if (mappedPrefix) {
                prefix = mappedPrefix + ":";
            } else {
                prefix = "{" + node.namespaceURI + "}";
            }
            return prefix + node.localName;
        } else {
            return node.localName;
        }
    }

    return promises.resolve(convertNode(document.documentElement));
}