2012-09-05 21 views
20

Estoy tratando de convertir esta tabla HTML:Cómo convertir tabla HTML para Javascript Object con jQuery

enter image description here

Código:

<table id="students" border="1"> 
    <thead> 
     <tr> 
      <th>Name</th> 
      <th>Age</th> 
      <th>Grade</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr class="student"> 
      <td>Oscar</td> 
      <td>23</td> 
      <td>16.5</td>   
     </tr> 
     <tr class="student"> 
      <td>Antonio</td> 
      <td>32</td> 
      <td>14</td>   
     </tr> 
     <tr class="student"> 
      <td>Jessica</td> 
      <td>21</td> 
      <td>19</td>   
     </tr> 
    </tbody> 
</table>​​​​​​ 

en un objeto javascript usando jQuery:

var tbl = $('table#students tr').map(function() { 
    return $(this).find('td').map(function() { 
    return $(this).text(); 
    }).get(); 
}).get(); 

La salida de código de voluntad por encima de la matriz siguiente:

["Oscar", "23", "16.5", "Antonio", "32", "14", "Jessica", "21", "19"] 

Todo es bueno en este punto, pero ¿cómo se puede hacer si quiero que los objetos JavaScript dentro de la matriz a tener la siguiente estructura:

[{id:1, name: "Oscar", age: 23, grade: 16.5}, {id:2, name: "Antonio", age: 32, grade: 14}, {id:3, name: "Jessica", age: 21, grade: 19}] 

enter image description here

Sólo para ser más específicos ...

  • El id se obtiene de la tr
  • Los name, age y grade valores se obtienen de cada fila

Hice este jsfiddle para probar:

http://jsfiddle.net/oscarj24/ptVDm/

Gracias

+1

El segundo ejemplo es ** NO JSON **. Es un ** objeto de JavaScript **. Demasiadas personas ya están confundidas sobre lo que es JSON, así que voy a ser exigente y lo señalaré. – Aesthete

+0

es muy simple, pero debo decir que necesité algo de tiempo para hacerlo bien: JSON es un formato de serialización ('stringification'). si no es una cadena, no es JSON; si es una cadena, puede o no analizarse como JSON válido. cuando alguien dice 'un objeto JSON', entonces lo que podrían querer decir es 'un valor de datos que se serializa fácilmente como JSON' (que no es cierto para todos los valores). – flow

Respuesta

24
var tbl = $('#students tr:has(td)').map(function(i, v) { 
    var $td = $('td', this); 
     return { 
       id: ++i, 
       name: $td.eq(0).text(), 
       age: $td.eq(1).text(), 
       grade: $td.eq(2).text()    
       } 
}).get(); 

7

La siguiente debería funcionar:

var cols = []; 
var result = []; 
$('#students>thead>th').each(function(){ 
    cols.push($(this).text().toLowerCase()); 
}); 
$('#students>tbody>tr').each(function(id){ 
    var row = {'id': id+1}; 
    $(this).find('td').each(function(index){ 
     row[cols[index]] = $(this).text(); 
    }); 
    result.push(row); 
}); 

console.log(result); 

Básicamente, creo que las propiedades de los objetos de la cabeza de mesa, al lado se crea un objeto para cada fila, la asignación de valores a los nombres de propiedad como se dedujeron de la matriz anterior.

Algunos defectos obvios:

  • Si los datos de la tabla en realidad se diferencia por alguna razón, (por ejemplo, las filas vacías para cosméticos), este sistema va a poner objetos vacíos en la matriz resultante.
  • Si usa el atributo colspan en la tabla, este sistema no replicará automáticamente el mismo valor en diferentes propiedades de objeto, sino que limitará la configuración al <td> s restante.

Al ver el enfoque de Josiah, es probablemente más rápido que el mío ya que el mío trata de ser más inteligente al encontrar los nombres de las propiedades. Recomendaría su técnica si está seguro de que la estructura de su mesa no cambiará.De lo contrario, necesitarías algo en las líneas de mi código.

Ah, y para completar, here's a JSFiddle with mine.

4

Ver updated violín. La matriz adicional map es innecesaria porque está buscando un objeto literal para su JSON en este momento.

var data = $('table#students tbody tr').map(function(index) { 
    var cols = $(this).find('td'); 
    return { 
     id: index + 1, 
     name: cols[0].innerHTML,   // use innerHTML 
     age: (cols[1].innerHTML + '') * 1, // parse int 
     grade: (cols[2].innerHTML + '') * 1 // parse int 
    }; 
}).get(); 
+0

En su violín, desea console.log (datos) no console.log (tbl). – VictorKilo

+0

Gracias, actualizado. –

1

Trate a continuación aproximación para n columnas

DEMO:http://jsfiddle.net/ptVDm/7/

var tblhdr = $('table#students th').map(function() { 
    return $(this).text(); 
}).get(); 

console.log(tblhdr); 

var tbl = $('table#students tbody tr').map(function(idx, el) { 
    var td = $(el).find('td'); 
    var obj = {id: idx+1}; 

    //Can work on number of columns 
    for (var i = 0; i < tblhdr.length; i++) { 
     obj[tblhdr[i]] = td.eq(i).text(); 
    } 

    return obj; 
}).get(); 

console.log(tbl); 
1

No sé si jQuery ayuda mucho en este caso, aquí hay un JS llanura solución que es razonablemente independiente de la estructura de la tabla. Solo requiere que la primera fila sea un encabezado (puede ser un elemento de sección de tabla diferente o no) y las filas 1+ son datos.

La tabla puede tener tantas columnas o filas como desee, si hay rowspan o colspans allí se confundirá con el resultado (pero jQuery tampoco lo ayudará con eso).

Se podría adaptarse fácilmente para usar específicamente la sección de encabezado de los nombres de propiedades y hacer caso omiso de una sección de pie de página:

function tableToObj(table) { 
    var rows = table.rows; 
    var propCells = rows[0].cells; 
    var propNames = []; 
    var results = []; 
    var obj, row, cells; 

    // Use the first row for the property names 
    // Could use a header section but result is the same if 
    // there is only one header row 
    for (var i=0, iLen=propCells.length; i<iLen; i++) { 
    propNames.push(propCells[i].textContent || propCells[i].innerText); 
    } 

    // Use the rows for data 
    // Could use tbody rows here to exclude header & footer 
    // but starting from 1 gives required result 
    for (var j=1, jLen=rows.length; j<jLen; j++) { 
    cells = rows[j].cells; 
    obj = {}; 

    for (var k=0; k<iLen; k++) { 
     obj[propNames[k]] = cells[k].textContent || cells[k].innerText; 
    } 
    results.push(obj) 
    } 
    return results; 
} 
8

que necesitaba esta cosa exacta, excepto que necesitaba más características para ser capaz de anular la columna nombres e ignorar las filas ocultas. Escribí un plugin de jQuery que hace precisamente eso, que se encuentra aquí https://github.com/lightswitch05/table-to-json

por su ejemplo que haría: (http://jsfiddle.net/ptVDm/118/)

var table = $('#students').tableToJSON(); 

Una cosa a destacar es que los identificadores no son parte del objeto resultante . Podrías obtener la identificación de la ubicación de la matriz del objeto. O si realmente necesita que sea parte del objeto, puede crear una columna oculta para los ID y luego se incluirán

+0

Existe un problema con este enfoque cuando va a usar 'rowspan' o' colspan' en la tabla. Para la mesa normal, está perfectamente bien. – D3V

+0

@ D3V - Tiene razón, no he agregado ningún soporte para 'rowspan' o' colspan'. Usted es más que bienvenido para agregar soporte y fusionaré los cambios si lo desea – lightswitch05

+0

@ lightswitch05: Tenía un requisito donde tenía que tenerlos en cuenta. Calculé el índice de cada valor de atributo sobre la marcha y tenía un caché para almacenarlos y trasladar esos valores para que todas las claves se alinearan correctamente con el nombre de columna. Trataré de hacer que ese código sea más genérico y combinarlo con el complemento. – D3V

Cuestiones relacionadas