初始化代码
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Expose `parse`.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parse the given string of `xml`.
|
||||
*
|
||||
* @param {String} xml
|
||||
* @return {Object}
|
||||
* @api public
|
||||
*/
|
||||
function parse(xml) {
|
||||
xml = xml.trim(); // strip comments
|
||||
|
||||
xml = xml.replace(/<!--[\s\S]*?-->/g, '');
|
||||
return document();
|
||||
/**
|
||||
* XML document.
|
||||
*/
|
||||
|
||||
function document() {
|
||||
return {
|
||||
declaration: declaration(),
|
||||
root: tag()
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Declaration.
|
||||
*/
|
||||
|
||||
|
||||
function declaration() {
|
||||
const m = match(/^<\?xml\s*/);
|
||||
if (!m) return; // tag
|
||||
|
||||
const node = {
|
||||
attributes: {}
|
||||
}; // attributes
|
||||
|
||||
while (!(eos() || is('?>'))) {
|
||||
const attr = attribute();
|
||||
if (!attr) return node;
|
||||
node.attributes[attr.name] = attr.value;
|
||||
}
|
||||
|
||||
match(/\?>\s*/);
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* Tag.
|
||||
*/
|
||||
|
||||
|
||||
function tag() {
|
||||
const m = match(/^<([\w-:.]+)\s*/);
|
||||
if (!m) return; // name
|
||||
|
||||
const node = {
|
||||
name: m[1],
|
||||
attributes: {},
|
||||
children: []
|
||||
}; // attributes
|
||||
|
||||
while (!(eos() || is('>') || is('?>') || is('/>'))) {
|
||||
const attr = attribute();
|
||||
if (!attr) return node;
|
||||
node.attributes[attr.name] = attr.value;
|
||||
} // self closing tag
|
||||
|
||||
|
||||
if (match(/^\s*\/>\s*/)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
match(/\??>\s*/); // content
|
||||
|
||||
node.content = content(); // children
|
||||
|
||||
let child;
|
||||
|
||||
while (child = tag()) {
|
||||
node.children.push(child);
|
||||
} // closing
|
||||
|
||||
|
||||
match(/^<\/[\w-:.]+>\s*/);
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* Text content.
|
||||
*/
|
||||
|
||||
|
||||
function content() {
|
||||
const m = match(/^([^<]*)/);
|
||||
if (m) return m[1];
|
||||
return '';
|
||||
}
|
||||
/**
|
||||
* Attribute.
|
||||
*/
|
||||
|
||||
|
||||
function attribute() {
|
||||
const m = match(/([\w:-]+)\s*=\s*("[^"]*"|'[^']*'|\w+)\s*/);
|
||||
if (!m) return;
|
||||
return {
|
||||
name: m[1],
|
||||
value: strip(m[2])
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Strip quotes from `val`.
|
||||
*/
|
||||
|
||||
|
||||
function strip(val) {
|
||||
return val.replace(/^['"]|['"]$/g, '');
|
||||
}
|
||||
/**
|
||||
* Match `re` and advance the string.
|
||||
*/
|
||||
|
||||
|
||||
function match(re) {
|
||||
const m = xml.match(re);
|
||||
if (!m) return;
|
||||
xml = xml.slice(m[0].length);
|
||||
return m;
|
||||
}
|
||||
/**
|
||||
* End-of-source.
|
||||
*/
|
||||
|
||||
|
||||
function eos() {
|
||||
return xml.length == 0;
|
||||
}
|
||||
/**
|
||||
* Check for `prefix`.
|
||||
*/
|
||||
|
||||
|
||||
function is(prefix) {
|
||||
return xml.indexOf(prefix) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = parse;
|
||||
Reference in New Issue
Block a user