diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-08-16 14:21:25 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-08-16 14:22:46 +0100 |
| commit | 9ff57bb770e0296bb2f5b7a41711c53954eb8c4e (patch) | |
| tree | 048868d884058f59ed54b41f560d9c234de67c62 /lib/xmlreader.js | |
| parent | 883af29dfdbf98d1e0a61d459ffeb08b0b5a34a6 (diff) | |
Split xmlreader into nodes and reader modules
Diffstat (limited to 'lib/xmlreader.js')
| -rw-r--r-- | lib/xmlreader.js | 141 |
1 files changed, 0 insertions, 141 deletions
diff --git a/lib/xmlreader.js b/lib/xmlreader.js deleted file mode 100644 index 551366f..0000000 --- a/lib/xmlreader.js +++ /dev/null @@ -1,141 +0,0 @@ -var promises = require("./promises"); -var sax = require("sax"); -var _ = require("underscore"); - -exports.read = read; -exports.Element = Element; - -function read(xmlString, namespaceMap) { - namespaceMap = namespaceMap || {}; - - var finished = false; - var parser = sax.parser(true, {xmlns: true, position: false}); - - var rootElement = {children: []}; - var currentElement = rootElement; - var stack = []; - - var deferred = promises.defer(); - - parser.onopentag = function(node) { - var attributes = mapObject(node.attributes, function(attribute) { - return attribute.value; - }, mapName); - - var element = new Element(mapName(node), attributes); - currentElement.children.push(element); - stack.push(currentElement); - currentElement = element; - }; - - function mapName(node) { - if (node.uri) { - var mappedPrefix = namespaceMap[node.uri]; - var prefix; - if (mappedPrefix) { - prefix = mappedPrefix; - } else { - prefix = "{" + node.uri + "}"; - } - return prefix + ":" + node.local; - } else { - return node.local; - } - } - - parser.onclosetag = function(node) { - currentElement = stack.pop(); - }; - - parser.ontext = function(text) { - if (currentElement !== rootElement) { - currentElement.children.push({ - type: "text", - value: text - }); - } - }; - - parser.onend = function() { - if (!finished) { - finished = true; - deferred.resolve({ - root: rootElement.children[0] - }); - } - }; - - parser.onerror = function(error) { - if (!finished) { - finished = true; - deferred.reject(error); - } - }; - - parser.write(xmlString).close(); - - return deferred.promise; -} - -function mapObject(input, valueFunc, keyFunc) { - return _.reduce(input, function(result, value, key) { - var mappedKey = keyFunc.call(null, value, key, input); - result[mappedKey] = valueFunc.call(null, value, key, input); - return result; - }, {}); -} - -var emptyElement = { - first: function() { - return null; - }, - firstOrEmpty: function() { - return emptyElement; - }, - attributes: {} -}; - -function Element(name, attributes, children) { - this.type = "element"; - this.name = name; - this.attributes = attributes || {}; - this.children = children || []; -} - -Element.prototype.first = function(name) { - return _.find(this.children, function(child) { - return child.name == name; - }); -}; - -Element.prototype.firstOrEmpty = function(name) { - return this.first(name) || emptyElement; -}; - -Element.prototype.getElementsByTagName = function(name) { - var elements = _.filter(this.children, function(child) { - return child.name == name; - }); - return toElementList(elements); -}; - -Element.prototype.text = function() { - if (this.children.length === 0) { - return ""; - } else if (this.children.length !== 1 || this.children[0].type !== "text") { - throw new Error("Not implemented"); - } - return this.children[0].value; -}; - -var elementListPrototype = { - getElementsByTagName: function(name) { - return toElementList(_.flatten(this.map(function(element) { - return element.getElementsByTagName(name); - }, true))); - } -}; - -function toElementList(array) { - return _.extend(array, elementListPrototype); -} |
