我有一个以下结构的文件。它不是XML,但我需要以某种方式从中创建一个JSON。
所以虽然我希望该文件看起来像这样:
<chapter>
<line> Some text which I want to grab. </line>
<line> Some more text which I want to grab. </line>
<line> Even more text which I want to grab. </line>
</chapter>
实际上结构如下:
<chapter>
<line /> Some text which I want to grab.
<line /> Some more text which I want to grab.
<line /> Even more text which I want to grab.
</chapter>
所以&#39;&#39;每章只是站在自闭线标签旁边。你能推荐一种抓住这些的方法吗?可能在javascript / nodejs?
答案 0 :(得分:2)
格式是有效的XML,因此您可以使用常规XML技术...即DOMParser
来解析内容
但是,你只需要对解析这些行有点聪明 - 你想要找到每一行,并收集所有兄弟节点作为文本节点(应该只有一个,但我提供的代码不是做出任何假设)
你没有指定输出“结构”,但这里有一个你可以用来输出嵌套数组的方法 - 第一级是章节,每一章都有一个行数
var xml = `<chapter>
<line /> Some text which I want to grab.
<line /> Some more text which I want to grab.
<line /> Even more text which I want to grab.
</chapter>`
var parser = new DOMParser();
var content = parser.parseFromString(xml, 'application/xml')
var chapters = content.getElementsByTagName('chapter');
var obj = [].reduce.call(chapters, function(result, chapter) {
var lines = chapter.getElementsByTagName('line');
result.push([].reduce.call(lines, function(result, line) {
var text = '';
for(var node = line.nextSibling; node && node.nodeType == 3; node = node.nextSibling) {
text += node.nodeValue;
}
result.push(text);
return result;
}, []))
return result;
}, []);
console.log(JSON.stringify(obj));
解决评论 - 首先是一些文档:
现在,在此代码中解释[].reduce.call(array, fn)
[].reduce.call
是Array.prototype.reduce.call
getElementsByTagName
返回一个HTMLCollection
...其行为类似于一个数组,除了它不是一个......有几种方法可以从HTMLCollection中创建一个数组 - 最原始的:
var array = [];
for(var i = 0; i < collection.length; i++) {
array[i] = collection[i];
}
或
var array = Array.prototype.slice.call(collection);
或(ES2015 +) - 除非您填充,否则在IE中不可用 - 请参阅文档
var array = Array.from(collection);
但是,在.call
上使用[].reduce
方法允许第一个参数(this
参数)是任何可迭代的,而不仅仅是一个数组,所以它就像使用{{ 1}}从上面开始像array
- 这是一种像处理数组一样处理HTMLcollection的方法,而不需要中间变量