使用jQuery通过循环创建和填充JSON对象

时间:2015-03-04 22:25:40

标签: javascript jquery

我正在尝试使用一些多个.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文件:

.XML Victim

更新

我越来越接近这个:

// 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"
}
]
...

3 个答案:

答案 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"
  }
  ...
}