2015-03-04 3 views
0

Я пытаюсь создать объект JSON динамически, используя несколько циклов .each(). Я попытался использовать .push(), но я смог получить только первый «уровень» объекта JSON (первый массив).Создание и заполнение объекта JSON с помощью jQuery через циклы

JS анализирует файл Excel (2003/XML) и должен выводить этот «стили» объекта JSON, чтобы я мог использовать его для генерации CSS на страницах (страницах). Таким образом, мы сохраняем таблицу Excel XML, мой JS использует AJAX для «GET», затем анализирует ее, извлекая стили (и рабочие листы/их данные). Процесс извлечения должен затем «динамически» создать этот объект 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: Объект».

SO, как я могу сгенерировать объект JSON «динамически», используя петли .each() и $ .each() выше?

Заранее благодарен!

P.S. Я искал совсем немного, чтобы попытаться найти ответ на это уже. Я нашел биты и куски о том, как сделать некоторые из этого, но ни один, населявшего объекта ... интеллектуально вырабатывать

EDIT:

Вот XML-файл, который я «разбор»:

.XML Victim

UPDATE:

Я получаю ближе с этим:

// 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

Это не JSON, это просто обычный объект Javascript. – Nit

+0

Вы бросили инструкцию отладчика перед назначением значения, чтобы узнать, что это за значение? – Daved

+0

@ Нит, так мне сказали. Я вижу '{' и '[', и я принимаю это за JSON. Не могли бы вы объяснить, что сделает этот «JSON»? Единственное, что я изменил с http://json.org/example, это «var styles = []» (заменил '{'' s на '['. Я вижу '[&]', используемый в" JSON " tutorials. Как это будет переработано как «JSON»? – derekmx271

ответ

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; 
     } 
     } 
    }); 
    }); 

Он возвращает объект, как вы описываете (хотя и правильно, как целевой переменной является неправильным, потому что это массив, но имеет структура объекта)

+0

Ницца. Я тоже поиграю с этим ... Он выглядит совершенно иначе, чем я, наконец, с кем-то ... Я обновляю свой ответ, когда мы говорим :) Спасибо за это. Я думаю, что ваш скрипт более оптимизирован, чем мой ... – derekmx271

+0

Я отметил это как ответ, потому что он обеспечивает именно то, что я попросил изначально. Вы, сэр, рок-звезда! Это отлично работает! Спасибо :) – derekmx271

0

Спасибо за размещение файла XML. Вместо использования this.name ссылайтесь на this.localName, чтобы получить имя, отличное от имени XML, - имя фактического узла. Это вернет массив объектов со стилями, определенными в них. Кроме того, поскольку вы используете массив, вы не сможете установить имя/идентификатор стиля. Вам нужно изменить «стили» на объект, и вы можете установить имя/идентификатор так же, как и для каждого стиля.

EDIT: Обновлено моим полным кодом, поскольку я что-то оставил, что могло бы действительно помочь вам.

Try:

$(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. 
    }); 
}); 
+0

Сладкий, получится! Отправляется обратно ... Спасибо! – derekmx271

+0

Это выводит то же самое, что и мой исходный скрипт ... Наверное, я не уверен, как вставлять значения в разные «уровни» объекта. Значения 'this.name' и' this.value' выводят правильные значения. Как ни странно, 'JSON.stringify (styles)' выводит '[]', а не то, что я ожидал (это была строка JSON-look с '{' и '['. – derekmx271

+0

Я обновил свой OP с некоторыми изменениями, которые, похоже, приблизили меня ... Может быть, это может пролить свет на то, что я могу сделать, чтобы получить желаемый результат? Спасибо за вашу помощь ... – derekmx271

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" 
    } 
    ... 
} 
+0

Я решил против «[», который, как все говорят, делает все это объектом. Я также удалил уровень с выхода. Не как компромисс, а потому, что это не было необходимо для того, что я хотел (что было способностью ссылаться на эти значения с помощью 'styles ['s57']. FontName' и тому подобное :) – derekmx271

+0

Думаю, я должен был также разработать тест, который я сделал. Я использовал jQuery.get() для загрузки XML. Я обновляю свой ответ с полным кодом, чтобы вы могли видеть, что я делаю. Извини за это. – Daved

+0

В конечном счете, я пошел с ответом @Gaby aka G. Petrioli ... – derekmx271

Смежные вопросы