我正在尝试使用一些多个.each()循环动态创建一个JSON对象。我尝试使用.push(),但我只能获得填充的JSON对象(第一个数组)的第一个“层”。
JS解析Excel Spreadsheet(2003 / XML)文件,需要输出这个JSON对象“styles”,这样我就可以用它在页面上生成CSS。所以基本上,我们保存了一个Excel XML Spreadsheet,我的JS使用AJAX来“获取”它,然后解析它提取样式(以及工作表/它们的数据)。然后,提取过程应“动态”创建此JSON对象,以便在JS文件的其他位置使用。
以下是在各种函数和循环完成后我需要JSON(除非有更好的结构或结构对我的情况更有意义)...
var styles = [
"Default": {
"Name": "Normal",
"Style": {
"Alignment": {
"Vertical": "Bottom"
},
"Font": {
"Name": "Calibri",
"Family": "Swiss",
"Size": "11",
"Color": "#000000"
}
}
},
"s57": {
"Name": "Hyperlink",
"Style": {
"Font": {
"Name": "Calibri",
"Family": "Swiss",
"Size": "11",
"Color": "#0066CC",
"Underline": "Single"
}
}
}
]
我的JS(到目前为止)
var styles = []
$(xml).find('Style').each(function(){
var style = {}
var id = $(this).attr('ss:ID');
var type = $(this).children();
type.each(function() {
$.each(this.attributes, function() {
if (this.specified) {
style[this.name] = this.value;
}
});
});
styles.push(style);
console.log(styles);
});
效果不好。添加style[this.name] = this.value
后,控制台显示了一堆“X:Object”条目。
那么,如何使用上面的.each()和$ .each()循环“动态”生成JSON对象?
提前致谢!
P.S。我已经搜索了很多,试图找到答案。我已经找到了关于如何做到这一点的点点滴滴,但没有一个能够智能地填充对象......
修改
这是我正在“解析”的XML文件:
更新
我越来越接近这个:
// Create JSON Object "styles"
var styles = [];
$(xml).find('Style').each(function(){
var style = {};
var id = $(this).attr('ss:ID');
var type = $(this).children();
type.each(function() {
$.each(this.attributes, function() {
if (this.specified) {
style[this.name] = this.value;
}
});
});
//styles[id] = style;
styles.push(style);
});
console.log(styles);
$(document).ready(function(){
$('body').append('<div class="json-output"/>');
$('.json-output').append(JSON.stringify(styles));
});
** JSON.stringify(styles)
现在正在使用上述脚本输出
[
{
"ss:Vertical":"Bottom",
"ss:FontName":"Calibri",
"x:Family":"Swiss",
"ss:Size":"11",
"ss:Color":"#000000"
},
"ss:FontName":"Calibri",
"x:Family":"Swiss",
"ss:Size":"11",
"ss:Color":"#0066CC",
"ss:Underline":"Single"
},
{
"ss:Horizontal":"Left",
"ss:Vertical":"Center",
"ss:Indent":"1"
}, {
"ss:Vertical":"Center",
"ss:WrapText":"1",
"ss:FontName":"Calibri",
"x:Family":"Swiss",
"ss:Size":"11",
"ss:Color":"#000000",
"ss:Bold":"1"
},
{
"ss:Vertical":"Center",
"ss:WrapText":"1",
"ss:FontName":"Calibri",
"x:Family":"Swiss",
"ss:Size":"11",
"ss:Color":"#008000",
"ss:Bold":"1"
},
{
"ss:Vertical":"Center",
"ss:WrapText":"1"
},
{
"ss:Vertical":"Center",
"ss:WrapText":"1",
"ss:FontName":"Calibri",
"x:Family":"Swiss",
"ss:Size":"11",
"ss:Color":"#808080",
"ss:Bold":"1",
"ss:Pattern":"Solid"
},
{
"ss:Horizontal":"Left",
"ss:Vertical":"Bottom"
},
{
"ss:Horizontal":"Left",
"ss:Vertical":"Center",
"ss:WrapText":"1",
"ss:Format":"0"
},
{
"ss:Horizontal":"Left",
"ss:Vertical":"Center",
"ss:Indent":"1",
"ss:WrapText":"1"
}
]
...
答案 0 :(得分:1)
您需要的是
var root = $(xml),
styles = {},
all = root.find('Style');
all.each(function(index, item){
var self = $(this),
id = self.attr('ss:ID'),
type = self.children(),
style = {};
styles[id] = style;
type.each(function(index, item){
var attributes = item.attributes;
if (attributes.length){
style[ item.nodeName ] = {};
for (var i = 0, l = attributes.length; i < l; i++){
var attribute = attributes[i],
attrName = attribute.nodeName;
if (attrName.indexOf(':') > -1){
attrName = attrName.split(':')[1];
}
style[ item.nodeName ][ attrName ] = attribute.value;
}
}
});
});
它将在您描述时返回一个对象(虽然正确,因为它是一个数组但是具有对象的结构,因为它的目标变量是错误的)
答案 1 :(得分:0)
感谢您发布XML文件。而不是使用this.name,引用this.localName来获取非XML命名空间名称 - 实际节点名称。这将返回一个对象数组,其中定义了样式。此外,由于您使用的是阵列,因此您无法设置样式的名称/ ID。你需要改变&#34;样式&#34;对于一个对象,您可以像对每种样式一样设置名称/ ID。
编辑:更新了我的完整代码,因为我遗漏了一些可能对您有所帮助的内容。
尝试:
$(function () {
$.get('/StackTest.xml', function (xml) { // i had it locally saved in my sandbox
var styles = {};
$(xml).find('Style').each(function () {
var style = {};
var id = $(this).attr('ss:ID');
var type = $(this).children();
type.each(function () {
$.each(this.attributes, function () {
if (this.specified) {
style[this.localName] = this.value;
}
});
});
styles[id] = style;
});
console.log(styles);
console.log(JSON.stringify(styles)); // see what it looks like as string - notice no array.
});
});
答案 2 :(得分:0)
所以这就是我最终的结果......
它允许我引用诸如styles['s57'].FontName
之类的东西(例如,具有s57样式的所有单元格的字体)。
// Get Excel Spreadsheet (2003/XML Only!)
$.ajax({
type: "GET",
url: '/data/KH-3140300109.xml',
dataType: "xml",
success: function(xml) {
console.log('%cgetExcel() was successful!', 'color:green; font-weight:bold;');
createStyles(xml);
},
error: function(){
console.error('getData() was unsuccessful');
}
});
function createStyles(xml) {
// Create JSON object "styles"
var styles = {}
$(xml).find('Style').each(function(){
var id = $(this).attr('ss:ID');
var name = $(this).attr('ss:Name');
var type = $(this).children();
// Create JSON object "style"
var style = {};
// Identify the style
styles[id] = style;
// Log its name
style['Name'] = name;
// Add various styles to that style
type.each(function() {
// Loop through each style-type and log it's values
$.each(this.attributes, function() {
// If it exists... Log it!
if (this.specified) {
style[stripPrefix(this.name)] = this.value;
}
});
});;
});
console.log('Moment of truth... ' + styles['s57'].FontName);
$(document).ready(function(){
$('body').append('<div class="json-output"/>');
$('.json-output').append(JSON.stringify(styles));
});
}
以下是它输出的内容(JSON-或其他任何内容......)
{
"Default":{
"Name":"Normal",
"Vertical":"Bottom",
"FontName":"Calibri",
"Family":"Swiss",
"Size":"11",
"Color":"#000000"
},
"s57":{
"Name":"Hyperlink",
"FontName":"Calibri",
"Family":"Swiss",
"Size":"11",
"Color":"#0066CC",
"Underline":"Single"
},
"s58":{
"Horizontal":"Left",
"Vertical":"Center",
"Indent":"1"
}
...
}