Работа над XmlParser
This commit is contained in:
@@ -352,7 +352,9 @@ class XmlParser extends NodeBase {
|
|||||||
return this.selectFirst(selector, self);
|
return this.selectFirst(selector, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
toJson(format = false) {
|
toJson(options = {}) {
|
||||||
|
const {format = false} = options;
|
||||||
|
|
||||||
if (format)
|
if (format)
|
||||||
return JSON.stringify(this.rawNodes, null, 2);
|
return JSON.stringify(this.rawNodes, null, 2);
|
||||||
else
|
else
|
||||||
@@ -395,7 +397,11 @@ class XmlParser extends NodeBase {
|
|||||||
|
|
||||||
if (node.attrs) {
|
if (node.attrs) {
|
||||||
for (const [attrName, attrValue] of node.attrs) {
|
for (const [attrName, attrValue] of node.attrs) {
|
||||||
|
if (typeof(attrValue) === 'string')
|
||||||
attrs += ` ${attrName}="${attrValue}"`;
|
attrs += ` ${attrName}="${attrValue}"`;
|
||||||
|
else
|
||||||
|
if (attrValue)
|
||||||
|
attrs += ` ${attrName}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,11 +416,11 @@ class XmlParser extends NodeBase {
|
|||||||
close = (deepType === NODE ? ' '.repeat(depth) : '') + close + '\n';
|
close = (deepType === NODE ? ' '.repeat(depth) : '') + close + '\n';
|
||||||
}
|
}
|
||||||
} else if (node.type === TEXT) {
|
} else if (node.type === TEXT) {
|
||||||
body = node.value;
|
body = node.value || '';
|
||||||
} else if (node.type === CDATA) {
|
} else if (node.type === CDATA) {
|
||||||
//
|
body = `<![CDATA[${node.value || ''}]]>`;
|
||||||
} else if (node.type === COMMENT) {
|
} else if (node.type === COMMENT) {
|
||||||
//
|
body = `<!--${node.value || ''}-->`;
|
||||||
}
|
}
|
||||||
|
|
||||||
result += `${open}${body}${close}`;
|
result += `${open}${body}${close}`;
|
||||||
@@ -429,7 +435,89 @@ class XmlParser extends NodeBase {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fromSrtring() {
|
fromString(xmlString, options = {}, pickNode = () => true) {
|
||||||
|
const parsed = [];
|
||||||
|
const root = this.createNode(parsed);
|
||||||
|
let node = root;
|
||||||
|
|
||||||
|
let route = '';
|
||||||
|
let routeStack = [];
|
||||||
|
let ignoreNode = false;
|
||||||
|
|
||||||
|
const {lowerCase = false, whiteSpace = false} = options;
|
||||||
|
|
||||||
|
const onStartNode = (tag, tail, singleTag, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars
|
||||||
|
if (tag == '?xml')
|
||||||
|
return;
|
||||||
|
|
||||||
|
route += `/${tag}`;
|
||||||
|
ignoreNode = !pickNode(route);
|
||||||
|
|
||||||
|
const newNode = this.createNode(tag);
|
||||||
|
|
||||||
|
routeStack.push({tag, route, ignoreNode, node: newNode});
|
||||||
|
|
||||||
|
if (ignoreNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tail) {
|
||||||
|
const parsedAttrs = sax.getAttrsSync(tail, lowerCase);
|
||||||
|
const attrs = new Map();
|
||||||
|
for (const attr of parsedAttrs.values()) {
|
||||||
|
attrs.set(attr.fn, attr.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs.size)
|
||||||
|
newNode.attrs = attrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node.value)
|
||||||
|
node.value = [];
|
||||||
|
node.value.push(newNode.raw);
|
||||||
|
node = newNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onEndNode = (tag, tail, singleTag, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars
|
||||||
|
if (routeStack.length && routeStack[routeStack.length - 1].tag === tag) {
|
||||||
|
routeStack.pop();
|
||||||
|
|
||||||
|
if (routeStack.length) {
|
||||||
|
const last = routeStack[routeStack.length - 1];
|
||||||
|
route = last.route;
|
||||||
|
ignoreNode = last.ignoreNode;
|
||||||
|
node = last.node;
|
||||||
|
} else {
|
||||||
|
route = '';
|
||||||
|
ignoreNode = false;
|
||||||
|
node = root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onTextNode = (text, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars
|
||||||
|
if (ignoreNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!whiteSpace && text.trim() == '')
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!node.value)
|
||||||
|
node.value = [];
|
||||||
|
|
||||||
|
node.value.push(this.createText(text).raw);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCdata = (tagData, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars
|
||||||
|
}
|
||||||
|
|
||||||
|
const onComment = (tagData, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars
|
||||||
|
}
|
||||||
|
|
||||||
|
sax.parseSync(xmlString, {
|
||||||
|
onStartNode, onEndNode, onTextNode, onCdata, onComment, lowerCase
|
||||||
|
});
|
||||||
|
|
||||||
|
this.rawNodes = parsed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ async function parse(xstr, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getAttrsSync(tail, lowerCase = true) {
|
function getAttrsSync(tail, lowerCase = true) {
|
||||||
let result = {};
|
let result = new Map();
|
||||||
let name = '';
|
let name = '';
|
||||||
let value = '';
|
let value = '';
|
||||||
let vOpen = '';
|
let vOpen = '';
|
||||||
@@ -300,7 +300,7 @@ function getAttrsSync(tail, lowerCase = true) {
|
|||||||
[ns, name] = fn.split(':');
|
[ns, name] = fn.split(':');
|
||||||
}
|
}
|
||||||
|
|
||||||
result[name] = {value, ns, fn};
|
result.set(fn, {value, ns, name, fn});
|
||||||
}
|
}
|
||||||
name = '';
|
name = '';
|
||||||
value = '';
|
value = '';
|
||||||
|
|||||||
Reference in New Issue
Block a user