1 | var sax = require('sax');
|
2 |
|
3 | function Document(dom) {
|
4 | this.root = dom;
|
5 | }
|
6 |
|
7 | Document.prototype.find = function (name) {
|
8 | return this.root.find(name);
|
9 | };
|
10 |
|
11 |
|
12 | function Node(name) {
|
13 | this.name = name;
|
14 | this.attrs = {};
|
15 | this.children = [];
|
16 | this.parent = null;
|
17 | }
|
18 |
|
19 | Node.prototype.parents = function (name) {
|
20 | var cur = this.parent;
|
21 | var results = [];
|
22 | while (cur) {
|
23 | if (cur.name === name) {
|
24 | results.push(cur);
|
25 | }
|
26 | cur = cur.parent;
|
27 | }
|
28 | return results;
|
29 | };
|
30 |
|
31 | Node.prototype.find = function (name) {
|
32 | var results = [];
|
33 |
|
34 | function walk(node) {
|
35 | if (node.name === name) {
|
36 | results.push(node);
|
37 | }
|
38 |
|
39 | node.children.forEach(walk);
|
40 | }
|
41 |
|
42 | this.children.forEach(walk);
|
43 |
|
44 | return results;
|
45 | };
|
46 |
|
47 | exports.parseString = function parseString (str, options) {
|
48 | return new Promise(function (resolve, reject) {
|
49 | var parser = getParser(resolve, reject, options);
|
50 | parser.write(str).close();
|
51 | });
|
52 | };
|
53 |
|
54 | function getParser(callback, error, options) {
|
55 | options = options || {};
|
56 |
|
57 | var cur = new Node();
|
58 | cur.root = true;
|
59 |
|
60 | var parser = sax.parser(options.strict || true, options);
|
61 |
|
62 | parser.onerror = function (e) {
|
63 | error(e);
|
64 | };
|
65 |
|
66 | parser.onopentag = function (obj) {
|
67 | var o = new Node(obj.name);
|
68 | if (obj.attributes) {
|
69 | o.attrs = obj.attributes;
|
70 | }
|
71 | o.parent = cur;
|
72 | cur.children.push(o);
|
73 | cur = o;
|
74 | };
|
75 |
|
76 | parser.onclosetag = function () {
|
77 | cur = cur.parent;
|
78 | if (!cur.parent) {
|
79 | callback(new Document(cur));
|
80 | }
|
81 | };
|
82 |
|
83 | parser.oncdata = function(cdata) {
|
84 | cur.cdata = cdata;
|
85 | };
|
86 |
|
87 | parser.ontext = function (text) {
|
88 | if (!cur.value) {
|
89 | cur.value = '';
|
90 | }
|
91 | cur.value += text;
|
92 | };
|
93 |
|
94 | return parser;
|
95 | }
|