aboutsummaryrefslogtreecommitdiff
path: root/lib/xml/reader.js
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2022-11-27 15:01:01 +0000
committerMichael Williamson <mike@zwobble.org>2023-02-07 19:39:26 +0000
commit0894561a06782812a4e73725ede6642da4501db0 (patch)
treea3d30a820bcb8a9de7789f5ee1899d99e1215f1e /lib/xml/reader.js
parentaecb9ed67bd2f73275442493b69e88e648273e56 (diff)
Replace sax with xmldom
Diffstat (limited to 'lib/xml/reader.js')
-rw-r--r--lib/xml/reader.js112
1 files changed, 49 insertions, 63 deletions
diff --git a/lib/xml/reader.js b/lib/xml/reader.js
index 0c2e7f5..41aabde 100644
--- a/lib/xml/reader.js
+++ b/lib/xml/reader.js
@@ -1,83 +1,69 @@
var promises = require("../promises");
-var sax = require("sax");
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 || {};
-
- 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];
+
+ 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 = {};
+ _.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.uri + "}";
+ prefix = "{" + node.namespaceURI + "}";
}
- return prefix + node.local;
+ return prefix + node.localName;
} else {
- return node.local;
+ return node.localName;
}
}
-
- parser.onclosetag = function(node) {
- currentElement = stack.pop();
- };
-
- parser.ontext = function(text) {
- if (currentElement !== rootElement) {
- currentElement.children.push(nodes.text(text));
- }
- };
-
- parser.onend = function() {
- if (!finished) {
- finished = true;
- deferred.resolve(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(value, key, input);
- result[mappedKey] = valueFunc(value, key, input);
- return result;
- }, {});
+ return promises.resolve(convertNode(document.documentElement));
}