手写XML转化为JS对象方法
2021-01-15 04:13
标签:int state sub als psu unshift lazy 集合 attr 实现思路: 提取出XML的首行声明 将XML拆分为 开始标签 结束标签 文本三部分 利用栈结构校验标签是否正确匹配 遍历构建标签对象,文本对象,并为他们打上ID和父级指向ID 对实体引用进行字符替换 把这些单个对象构建成最终的结果并返回 例子: XML: 24 垃圾王者队友不配赢 构建的JS对象: 可自行验证更复杂的XML 手写XML转化为JS对象方法 标签:int state sub als psu unshift lazy 集合 attr 原文地址:https://www.cnblogs.com/zhenfeishi/p/13399233.htmlfunction xml(str, is = true){ //解析XML
/* 定义返回的对象 */
let result = { //解析成功返回的对象(标签名,属性集合对象[属性名:属性值...],子元素数组[{}, {}...])
meta: ‘‘,
xml: {}
};
/* 提取首行说明 */
str = str.trim(); //字符串去除两边空白
for(let i = 0, len = str.length; i //提取首行声明
if(str[i] == ‘>‘){
result.meta = str.slice(0, i + 1);
str = str.slice(i + 1);
break;
}
}
str = str.trim();
/* 找出可以分割的点 */
let subList = [], //切割点下标集合
state = false, //是否进入标签区域
tempSub = -1; //临时存储下标
for(let i = 0, len = str.length; i i){
if(state){
if(str[i] == ‘>‘){
subList.push(i + 1);
state = false;
}
}else{
if(str[i] == ‘){
if(tempSub != -1){
subList.push(tempSub);
tempSub = -1;
}else{}
subList.push(i);
state = true;
}else{
if(tempSub == -1){
tempSub = i;
}
}
}
}
subList = Array.from(new Set(subList));
/* 执行分割 */
let elementList = [];
for(let i = 0, len = subList.length - 1; i i){
elementList.push(str.slice(subList[i], subList[i + 1]));
}
/* 校验是否符合规则 */
let stackCheck = [],
getEndLabelName = function(str){
str = str.replace(/\s*/g, "");
return str.slice(2, str.length - 1);
},
getStartLabelName = function(str, is = true){
let start = -1;
for(let i = 0, len = str.length; i i){
if(start == -1){
if(str[i] != ‘ i; }
}else{
if(str[i] == ‘ ‘ || str[i] == ‘>‘){
if(is){
return str.slice(start, i);
}else{
return i;
}
}
}
}
};
for(let i = 0, len = elementList.length; i i){
if(elementList[i][0] == ‘){
if(elementList[i].replace(/\s*/g, "")[1] == ‘/‘){ //结束标签
if(stackCheck[stackCheck.length - 1] != getEndLabelName(elementList[i])){
let tempTit = ‘标签匹配错误:‘ + stackCheck[stackCheck.length - 1] + ‘与‘ + getEndLabelName(elementList[i]) + ‘不匹配‘;
console.error(tempTit);
if(is){
return {};
}else{
return [];
}
}else{
stackCheck.splice(stackCheck.length - 1);
}
}else{ //开始标签
stackCheck.push(getStartLabelName(elementList[i]));
}
}
}
/* 如果is为false */
if(!is){
elementList.unshift(result.meta)
return elementList;
}
/* 构建零散对象,打上id和父级id */
stackCheck.push({ID: 0});
let eleObjList = [], //零散对象列表
ID = 0; //ID计数器
let getLabelAttribute = function(str){
str = str.slice(getStartLabelName(str, false));
str = str.slice(0, str.length - 1);
str = str.trim();
if(str == ""){ return {}; }
let stack = "";
for(let i = 0, len = str.length; i i){
if(str[i] == "‘" || str[i] == ‘"‘){
if(stack == ""){ stack = str[i]; }
else{
if(stack == str[i]){
stack = "";
}else{
return 0;
}
}
}
}
let list = [],
count = 0,
start = -1;
for(let i = 0, len = str.length; i i){
if(start == -1){
if((str[i].charCodeAt(0) >= 65 && str[i].charCodeAt(0) = 97 && str[i].charCodeAt(0) )){
start = i;
}
}else{
if(str[i] == "‘" || str[i] == ‘"‘){
++count;
}
if(count == 2){
list.push(str.slice(start, i + 1));
start = -1;
count = 0;
}
}
}
let result = {};
for(let i = 0, len = list.length; i i){
let tempArr = list[i].split("=");
tempArr[0] = tempArr[0].trim();
tempArr[1] = tempArr[1].trim();
tempArr[1] = tempArr[1].slice(1, tempArr[1].length - 1);
result[tempArr[0]] = tempArr[1];
}
return result;
};
for(let i = 0, len = elementList.length; i i){
if(elementList[i][0] == ‘){
if(elementList[i].replace(/\s*/g, "")[1] != ‘/‘){ //开始标签
++ID;
let temp = getLabelAttribute(elementList[i]);
if(typeof temp == "number"){ console.error("属性引号不匹配"); return; }
eleObjList.push({
ID: ID,
pID: stackCheck[stackCheck.length - 1].ID,
label: getStartLabelName(elementList[i]),
attribute: temp,
children: []
});
stackCheck.push({ID: ID});
}else{ //结束标签
stackCheck.splice(stackCheck.length - 1);
}
}else{
++ID;
eleObjList.push({
text: elementList[i],
pID: stackCheck[stackCheck.length - 1].ID,
ID: ID
});
}
}
/* 对实体引用进行字符替换 */
let replaceXML = function(str){
str = str.replace(/</g, ");
str = str.replace(/>/g, ">");
str = str.replace(/&/g, "&");
str = str.replace(/'/g, "‘");
str = str.replace(/"/g, ‘"‘);
return str;
};
for(let i = 0, len = eleObjList.length; i i){
if(eleObjList[i].text == undefined){
for(let key in eleObjList[i].attribute){
eleObjList[i].attribute[key] = replaceXML(eleObjList[i].attribute[key]);
}
}else{
eleObjList[i].text = replaceXML(eleObjList[i].text);
}
}
/* 构建最终对象 */
for(let i = eleObjList.length - 1; i > 0; --i){
eleObjList[eleObjList[i].pID - 1].children.unshift(eleObjList[i]);
eleObjList[i].ID = eleObjList[i].pID = undefined;
}
eleObjList[0].ID = eleObjList[0].pID = undefined;
result.xml = eleObjList[0];
return result;
}