cnavarreteliz
cnavarreteliz

Reputation: 139

Convert table HTML to JSON

I have this:

<table>
    <tr>
        <th>Name:</th>
        <td>Carlos</td>
    </tr>        
    <tr>
        <th>Age:</th>
        <td>22</td>
    </tr>
</table>

And I need a JSON format.

{"Name":"Carlos","Age": 22}

I've tried with https://github.com/lightswitch05/table-to-json but it doesn't work for the headings in every row :(

EDIT: http://jsfiddle.net/Crw2C/773/

Upvotes: 4

Views: 17818

Answers (4)

user3544404
user3544404

Reputation: 21

var t = document.querySelector("table");

var j = [].reduce.call(t.rows, function(res, row) {
    res[row.cells[0].textContent.slice(0,-1)] = row.cells[1].textContent;
    return res
}, {});

document.querySelector("pre").textContent = JSON.stringify(j);
<table>
    <tr>
        <th>Name:</th>
        <td>Carlos</td>
    </tr>        
    <tr>
        <th>Age:</th>
        <td>22</td>
    </tr>
</table>
<pre></pre>

Upvotes: 2

sfletche
sfletche

Reputation: 49704

The Table-to-JSON library that you are using is expecting a different format in your table.

It is expecting a table with all of your headers in the first row, followed by the data in subsequent rows.

In other words, it's expecting your table to be structured like this

<table>
    <tr>
        <th>Name</th>
        <th>Age</th>
    </tr>        
    <tr>
        <td>Carlos</td>
        <td>22</td>
    </tr>
</table>

Here's a forked version of your JSFiddle in which this is working.

Upvotes: -1

user1106925
user1106925

Reputation:

Assuming all you need is to get the first/second cells of each row as key/value pairs, you can use .reduce() to iterate of the rows and just grab the text content of .cells[0] and .cells[1] to use as each key/value pair:

var t = document.querySelector("table");

var j = [].reduce.call(t.rows, function(res, row) {
    res[row.cells[0].textContent.slice(0,-1)] = row.cells[1].textContent;
    return res
}, {});

document.querySelector("pre").textContent = JSON.stringify(j, null, 2);
<table>
    <tr>
        <th>Name:</th>
        <td>Carlos</td>
    </tr>        
    <tr>
        <th>Age:</th>
        <td>22</td>
    </tr>
</table>
<pre></pre>

The Array.prototype.reduce method takes a collection and uses an accumulator to reduce it down to whatever state you want. Here we just reduce it to an object, so we pass one in after the callback.

For every row, we use the first cell's content as the object key, and the second cell's content as the value. We then return the object from the callback so that it's given back to us in the next iteration.

Finally, .reduce() returns the last thing we returned (which of course is the object we started with), and that's your result.

Upvotes: 6

RobG
RobG

Reputation: 147343

You can convert the table in the OP to the required format by first converting it to an Object, then using JSON.stringify to get the required string:

<table id="t0">
    <tr>
        <th>Name:</th>
        <td>Carlos</td>
    </tr>        
    <tr>
        <th>Age:</th>
        <td>22</td>
    </tr>
</table>

<script>

function tableToJSON(table) {
  var obj = {};
  var row, rows = table.rows;
  for (var i=0, iLen=rows.length; i<iLen; i++) {
    row = rows[i];
    obj[row.cells[0].textContent] = row.cells[1].textContent
  }
  return JSON.stringify(obj);
}

console.log(tableToJSON(document.getElementById('t0'))); // {"Name:":"Carlos","Age:":"22"}"

</script>

However, that is an ad hoc solution, so will need some work to be adapted to a more general case. It shows the concept though.

Note that there is no guarantee that the object properties will be returned in the same order as they appear in the table, you may get {"Age:":"22","Name:":"Carlos"}.

Upvotes: 8

Related Questions