Javascript 将任意大小的列表解析为类似XML的字符串
我有一个排列如下的数组:Javascript 将任意大小的列表解析为类似XML的字符串,javascript,recursion,ecmascript-6,stack,logic,Javascript,Recursion,Ecmascript 6,Stack,Logic,我有一个排列如下的数组: let example_arr = [ "backend", [ "#host#www.example.com", "#port#80" ], "endpoints", [ "endpoint", [ "#external#/foo/bar/cat/mom
let example_arr =
[
"backend",
[
"#host#www.example.com",
"#port#80"
],
"endpoints",
[
"endpoint",
[
"#external#/foo/bar/cat/mom/",
"#internal#/banana/",
"params",
[
"param",
[
"#sourceValue#acis.usermove.md"
]
]
],
]
];
此数组需要解析为如下所示的字符串:
"
<backend host="www.example.com" port="80" />
<endpoints>
<endpoint external="/foo/bar/cat/mom/" internal="/banana/"/>
<params>
<param sourceValue="acis.usermove.md" />
</params>
</endpoint>
</endpoints>
"
”
"
我研究这个问题已经有一段时间了,但已经放弃了一次又一次的尝试。以下是我的最新尝试:
let str_answer = helper_string_builder(example_arr, 3);
function helper_string_builder(xml_list_data, depth) {
let string_builder = "";
for (let i = 0; i < xml_list_data.length; i++) {
if (Array.isArray(xml_list_data[i]) !== true) {
if (xml_list_data[i].charAt(0) !== "#" && xml_list_data[i].length > 1) {
if(typeof xml_list_data[i + 1] === "undefined"){
continue;
}
string_builder += " ".repeat(depth) + "<" + xml_list_data[i] + ">\n";
for (let j = 0; j < xml_list_data[i + 1].length; j++) {
if (j === 0) {
string_builder += " ".repeat(depth + 3)
}
string_builder +=
value_reader("name", xml_list_data[i + 1][j]) +
"=\"" +
value_reader("content", xml_list_data[i + 1][j]) +
"\" ";
}
string_builder += "\n" + " ".repeat(depth) + "</" + xml_list_data[i] + ">\n";
}
console.log(string_builder);
} else {
string_builder += helper_string_builder(xml_list_data[i], depth + 3);
}
}
return string_builder;
}
function value_reader(mode, str) {
str = str + '';
if (str.substring(0, 1) != '#') {
return 'ERROR';
}
if (mode === "name") {
let start_pos = str.indexOf('#') + 1;
let end_pos = str.indexOf('#', start_pos);
let name_cutout = str.substring(start_pos, end_pos);
return name_cutout;
} else if (mode === "content") {
let start_pos = str.indexOf('#') + 1;
let end_pos = str.indexOf('#', start_pos);
let content_cutout = str.substring(end_pos + 1);
return content_cutout;
} else {
throw new Error("Valid \'mode\' not passed in");
}
}
let str\u answer=helper\u string\u builder(示例3);
函数助手\u字符串\u生成器(xml\u列表\u数据,深度){
让字符串_builder=“”;
for(设i=0;i1){
if(xml列表数据类型[i+1]=“未定义”){
继续;
}
字符串生成器+=“”。重复(深度)+“\n”;
for(设j=0;j
不知道如何继续解决这个问题,我想知道是否有人可以帮助我。谢谢 您的输入格式非常复杂,因此我想我的主要建议是在树中遍历两次:
元素
对象树:每个对象都有一个标记名
属性、一个属性
数组和一个子对象
数组。
数组可以包含属性
实例,它们是属性
对{key,value}
数组可以包含子元素
实例元素
元素返回字符串
- 如果它是一个字符串,并且以
开头,那么它就是一个属性“#”
- 如果它是字符串而不是属性,则它是一个新的
元素
- 如果是数组,则该数组包含先前生成的
元素的内容
//递归创建包含属性和子元素的元素树
常量分区=xs=>xs.reduce(
([lastPart,…parts],x)=>{
开关(getType(x)){
案例要素:
返回[
元素(x),
…(最后一部分?[最后一部分]:[]),
…零件
];
案例阵列:
常量attrsUntil=x.findIndex(Attribute.isNoAttribute);
常量attrs=attrsUntil!=-1
?x.slice(0,attrsUntil)
:x;
const children=attrsUntil==-1
? []
:x.slice(attrsUntil);
返回[元素](
lastPart.tagName,
属性映射(Attribute.fromString),
分区(儿童)
),…部分];
违约:
返回[最后一部分,…部分];
}
},
[]
).reverse()
const getType=x=>
数组。isArray(x)?排列
:Attribute.isAttribute(x)?属性
:元素;
//一些实用新型和方法:
常量属性=(键,值)=>
({key,value});
Attribute.isAttribute=(str)=>
str.charAt&&str.charAt(0)==“#”;
Attribute.isNoAttribute=x=>!属性。isAttribute(x);
Attribute.fromString=str=>Attribute(
…str.split(“#”)切片(1)
);
常量元素=(标记名,属性=[],子元素=[])=>
({标记名,属性,子项});
例如_arr=
[
“后端”,
[
“#主机#www.example.com”,
“#端口#80”
],
“端点”,
[
“端点”,
[
“#外部#/foo/bar/cat/mom/”,
“#内部#/banana/”,
“params”,
[
“param”,
[
“#sourceValue#acis.usermove.md”
]
]
],
]
];
console.log(
分区(示例_arr)
);代码>天哪。。。这太神奇了。我一直在努力解决这个问题,而我提出的实现仍然衍生出一些模糊的错误。将我的逻辑与你的逻辑交换,代码立即变得可跟踪,输出一致。向你致敬,用户3297291!