Skip to content

Commit

Permalink
Replace sax with xmldom
Browse files Browse the repository at this point in the history
  • Loading branch information
mwilliamson committed Feb 7, 2023
1 parent aecb9ed commit 0894561
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 75 deletions.
112 changes: 49 additions & 63 deletions lib/xml/reader.js
Original file line number Diff line number Diff line change
@@ -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));
}
23 changes: 23 additions & 0 deletions lib/xml/xmldom.js
Original file line number Diff line number Diff line change
@@ -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;
25 changes: 14 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down

0 comments on commit 0894561

Please sign in to comment.