aboutsummaryrefslogtreecommitdiff
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
parentaecb9ed67bd2f73275442493b69e88e648273e56 (diff)
Replace sax with xmldom
-rw-r--r--lib/xml/reader.js112
-rw-r--r--lib/xml/xmldom.js23
-rw-r--r--package-lock.json25
-rw-r--r--package.json2
4 files changed, 87 insertions, 75 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));
}
diff --git a/lib/xml/xmldom.js b/lib/xml/xmldom.js
new file mode 100644
index 0000000..752c353
--- /dev/null
+++ b/lib/xml/xmldom.js
@@ -0,0 +1,23 @@
+var xmldom = require("@xmldom/xmldom");
+var dom = require("@xmldom/xmldom/lib/dom");
+
+function parseFromString(string) {
+ var error = null;
+
+ var domParser = new xmldom.DOMParser({
+ errorHandler: function(level, message) {
+ error = {level: level, message: message};
+ }
+ });
+
+ var document = domParser.parseFromString(string);
+
+ if (error === null) {
+ return document;
+ } else {
+ throw new Error(error.level + ": " + error.message);
+ }
+}
+
+exports.parseFromString = parseFromString;
+exports.Node = dom.Node;
diff --git a/package-lock.json b/package-lock.json
index 0971a2c..8052a3e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,13 +9,13 @@
"version": "1.5.1",
"license": "BSD-2-Clause",
"dependencies": {
+ "@xmldom/xmldom": "^0.8.6",
"argparse": "~1.0.3",
"bluebird": "~3.4.0",
"dingbat-to-unicode": "^1.0.1",
"jszip": "^3.7.1",
"lop": "^0.4.1",
"path-is-absolute": "^1.0.0",
- "sax": "~1.1.1",
"underscore": "^1.13.1",
"xmlbuilder": "^10.0.0"
},
@@ -33,6 +33,14 @@
"uglify-js": "~2.4.8"
}
},
+ "node_modules/@xmldom/xmldom": {
+ "version": "0.8.6",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.6.tgz",
+ "integrity": "sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/abbrev": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
@@ -2525,11 +2533,6 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
- "node_modules/sax": {
- "version": "1.1.6",
- "resolved": "http://registry.npmjs.org/sax/-/sax-1.1.6.tgz",
- "integrity": "sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA="
- },
"node_modules/set-immediate-shim": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
@@ -3104,6 +3107,11 @@
}
},
"dependencies": {
+ "@xmldom/xmldom": {
+ "version": "0.8.6",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.6.tgz",
+ "integrity": "sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg=="
+ },
"abbrev": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
@@ -5258,11 +5266,6 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
- "sax": {
- "version": "1.1.6",
- "resolved": "http://registry.npmjs.org/sax/-/sax-1.1.6.tgz",
- "integrity": "sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA="
- },
"set-immediate-shim": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
diff --git a/package.json b/package.json
index f531225..3fd5895 100644
--- a/package.json
+++ b/package.json
@@ -17,13 +17,13 @@
"url": "https://github.com/mwilliamson/mammoth.js.git"
},
"dependencies": {
+ "@xmldom/xmldom": "^0.8.6",
"argparse": "~1.0.3",
"bluebird": "~3.4.0",
"dingbat-to-unicode": "^1.0.1",
"jszip": "^3.7.1",
"lop": "^0.4.1",
"path-is-absolute": "^1.0.0",
- "sax": "~1.1.1",
"underscore": "^1.13.1",
"xmlbuilder": "^10.0.0"
},