从html表内容构建json

时间:2016-03-18 14:57:02

标签: javascript jquery

我有一些从Web服务返回的HTML。我无法控制HTML,因为它不是我的网络服务。此Web服务返回如下所示的HTML:

<table id="result">
  <tbody>
    <tr>
      <td><b>Name</b></td>
      <td>John Smith</td>
    </tr>

    <tr>
      <td valign="top"><b>Address: </b></td>
      <td>123 Oak Street<br>Chicago, IL 12345-9023</td>
    </tr>

    <tr>
      <td><b>Phone: </b></td>
      <td>123-456-7890</td>
    </tr>

    <tr>
      <td><b>Occupation: </b></td>
      <td>Teacher</td>
    </tr>

    <tr>
      <td><b>Status: </b></td>
      <td>ACTIVE</td>
    </tr>
  </tbody>
</table>

我知道这个表基本上是键值对。我知道左栏包含一个标签。我知道正确的列具有我感兴趣的值。我正在尝试获取值并将其放入JSON结构中。例如,我有

var json = {
  name: '',                 // How do I reference the name value in the table?
  address: '',              // How do I reference the address value in the table?
  phone: '',               // How do I reference the phone value in the table?
  occupation: '',          // etc.
  status: ''               // etc.
}

如何使用jQuery获取表值,以便我可以填充我的JSON?我知道我的桌子将一直是这种结构。

谢谢!

4 个答案:

答案 0 :(得分:2)

如果行的顺序永远不会改变,您可以通过以下方式访问内容:

var result = $('#result'),
    json = {
        name: result.find('tr:first > td:last').text(),
        address: result.find('tr:eq(1) > td:last').text(),
        phone: result.find('tr:eq(2) > td:last').text(),
        occupation: result.find('tr:eq(3) > td:last').text(),
        status: result.find('tr:eq(4) > td:last').text(),
    };

答案 1 :(得分:2)

这是我的版本。

HTML:

<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>

<table id="result">
  <tbody>
    <tr>
      <td><b>Name</b></td>
      <td>John Smith</td>
    </tr>

    <tr>
      <td valign="top"><b>Address: </b></td>
      <td>123 Oak Street<br>Chicago, IL 12345-9023</td>
    </tr>

    <tr>
      <td><b>Phone </b></td>
      <td>123-456-7890</td>
    </tr>

    <tr>
      <td><b>Occupation </b></td>
      <td>Teacher</td>
    </tr>

    <tr>
      <td><b>Status </b></td>
      <td>ACTIVE</td>
    </tr>
  </tbody>
</table>

<br>

<p id="jsonOutput"></p>

JQuery的:

var $output = $("#jsonOutput");
var $table = $("#result");
var generatedJson = {};

$table.find("tr").each(function(){
    //iterate each row

  var $row = $(this);
  var jsonPropertyName = $row.find("td:nth-child(1)").text().trim();
    var jsonPropertyValue = $row.find("td:nth-child(2)").text().trim();

  generatedJson[jsonPropertyName] = jsonPropertyValue;

});


$output.text(JSON.stringify(generatedJson));

输出:

{
    "Name": "John Smith",
    "Address": "123 Oak StreetChicago, IL 12345-9023",
    "Phone": "123-456-7890",
    "Occupation": "Teacher",
    "Status": "ACTIVE"
}

play in Fiddle

请务必注意,属性名称应该像变量名一样命名。所以没有奇怪的符号或空格。你需要自己做那个部分。这个例子不包括这个。

答案 2 :(得分:0)

如果订单发生变化,您可以像这样使用它:

/usr/lib64

答案 3 :(得分:0)

我建议用纯JavaScript(假设table添加到您的DOM中):

// using ECMAScript 2015, ES6, to assign variables using 'let',
// and Array.from() to convert the collection returned from
// document.querySelectorAll() into an Array so that we can
// use Array methods:
let rows = Array.from(document.querySelectorAll('#result tr')),

  // declaring an empty object, using Object literal syntax:
  result = {};

  // iterating over the rows Array, using Array.prototype.forEach()
  rows.forEach(function(row) {
  // 'row' here is the current array-element in the Array over
  // which we're iterating, the name is user-defined.

  // finding the first child of the row element, which must be
  // a <td> element, finding that <td> element's textContent
  // and trimming leading and trailing whitespace using
  // String.prototype.trim():
    let key = row.children[0].textContent.trim(),

  // finding the second <td> child of the row element,
  // because the value may contain new-lines we use 
  // String.prototype.replace() to replace one-or-more
  // white-space characters (\s+) globally (g) from
  // the textContent and replace it with a single white-
  // space character (the second argument). We then trim()
  // that resultant string, to remove leading/trailing
  // white-space:
      value = row.children[1].textContent.replace(/\s+/g,' ').trim();

    // assigning the key, and its value, to the Object:
    result[key] = value;
  });

console.log(JSON.stringify( result ));
  // {"Name":"John Smith","Address:":"123 Oak Street Chicago, IL 12345-9023","Phone:":"123-456-7890","Occupation:":"Teacher","Status:":"ACTIVE"}

let rows = Array.from(document.querySelectorAll('#result tr')),
  result = {};
rows.forEach(function(row) {
  let key = row.children[0].textContent.trim(),
    value = row.children[1].textContent.replace(/\s+/g, ' ');

  result[key] = value;
});

console.log(JSON.stringify( result ));
<table id="result">
  <tbody>
    <tr>
      <td><b>Name</b>
      </td>
      <td>John Smith</td>
    </tr>

    <tr>
      <td valign="top"><b>Address: </b>
      </td>
      <td>123 Oak Street
        <br>Chicago, IL 12345-9023</td>
    </tr>

    <tr>
      <td><b>Phone: </b>
      </td>
      <td>123-456-7890</td>
    </tr>

    <tr>
      <td><b>Occupation: </b>
      </td>
      <td>Teacher</td>
    </tr>

    <tr>
      <td><b>Status: </b>
      </td>
      <td>ACTIVE</td>
    </tr>
  </tbody>
</table>

JS Fiddle demo

对上述内容的修正,以便将其转换为函数:

// Again, using ECMAScript 2015, ES6

function valuesToObject(opts) {
  'use strict';

  // declaring the default settings:
  let settings = {

    // the common parent of the elements
    // containing both the label and value
    // elements (this is passed to
    // document.querySelectorAll() so must
    // be a valid CSS selector):
    'labelValuesParent': 'tr',

    // the index of the label element
    // among the common parent's children:
    'labelIndex': 0,

    // the index of the value element
    // among the common parent's children:
    'valueIndex': 1
  };

  // if we have an opts Object passed in by the user/script,
  // and that Object has a 'from' property:
  if (opts && opts['from']) {

    // we iterate over the Array of Object keys from the
    // opts Object, using Array.prototype.forEach():
    Object.keys(opts).forEach(function(key) {
      // 'key' is the current array-element of the
      // array, the name is user-specified.

      // setting the key property of the settings Object
      // to the value of opts[ key ] value:
      settings[key] = opts[key];
    });

    // for no reason other than brevity, this can be omitted
    // so long as you remember to update the Object name
    // elsewhere or simply declare the initial 'settings'
    // Object with the name of 's':
    let s = settings,

      // if the s.from (which we checked existed already)
      // has a nodeType and that nodeType is 1 (therefore
      // it is an HTMLElement node) we simply assign s.from
      // to the container variable; otherwise we (naively)
      // assume it's a String, and pass it to
      // document.querySelector() to find the first/only
      // matching that selector:
      container = s.from.nodeType && s.from.nodeType === 1 ? s.from : document.querySelector(s.from),

      // from the found container we use document.querySelectorAll()
      // to retrieve the common parent-elements of the label-value
      // pairs found within the container:
      labelValues = container.querySelectorAll(s.labelValuesParent),

      // initialising an empty Object:
      result = {},

      // declaring, not initialising, two variables for use
      // within the following forEach():
      k, v;

    // converting the collection offound parent elements
    // into an Array, using Array.from(), and iterating
    // over that Array using Array.prototype.forEach():
    Array.from(labelValues).forEach(function(parent) {

      // finding the label text by finding the element
      // children of the parent, and finding its textContent
      // using the supplied index property:
      k = parent.children[s.labelIndex].textContent,

        // finding the value text by finding the element
        // children of the parent, and finding its textContent
        // using the supplied index property:
        v = parent.children[s.valueIndex].textContent;

      // setting the trimmed key value (removing leading
      // and trailing white-space) as a new key of the
      // result Object, and setting the value of that
      // property to the textContent of the value-element,
      // after replacing sequences of white-space with
      // single white-space characters, and then trimming
      // leading and trailing space using
      // String.prototype.trim():
      result[k.trim()] = v.replace(/\s+/g, ' ').trim();

    });

    // returning the JSON stringified String
    // from the result Object
    return JSON.stringify(result);

  }

  // if there was no opts.key property we simply return
  // null, because we have no way of anticipating which
  // element might contain the label-value pairs:
  return null;

}

console.log(valuesToObject({
  'from': '#result'
}));
// {"Name":"John Smith","Address:":"123 Oak Street Chicago, IL 12345-9023","Phone:":"123-456-7890","Occupation:":"Teacher","Status:":"ACTIVE"}

function valuesToObject(opts) {
  'use strict';
  let settings = {
    'labelValuesParent': 'tr',
    'labelIn': 'td',
    'valueIn': 'td',
    'labelIndex': 0,
    'valueIndex': 1
  };

  if (opts && opts['from']) {
    Object.keys(opts).forEach(function(key) {
      settings[key] = opts[key];
    });

    let s = settings,
      container = s.from.nodeType && s.from.nodeType === 1 ? s.from : document.querySelector(s.from),
      labelValues = container.querySelectorAll(s.labelValuesParent),
      result = {},
      k, v;

    Array.from(labelValues).forEach(function(parent) {
      k = parent.children[s.labelIndex].textContent,
        v = parent.children[s.valueIndex].textContent;

      result[k.trim()] = v.replace(/\s+/g, ' ').trim();

    });

    return JSON.stringify(result);

  }

  return null;

}

console.log(valuesToObject({
  'from': '#result'
}));
// {"Name":"John Smith","Address:":"123 Oak Street Chicago, IL 12345-9023","Phone:":"123-456-7890","Occupation:":"Teacher","Status:":"ACTIVE"}
<table id="result">
  <tbody>
    <tr>
      <td><b>Name</b>
      </td>
      <td>John Smith</td>
    </tr>

    <tr>
      <td valign="top"><b>Address: </b>
      </td>
      <td>123 Oak Street
        <br>Chicago, IL 12345-9023</td>
    </tr>

    <tr>
      <td><b>Phone: </b>
      </td>
      <td>123-456-7890</td>
    </tr>

    <tr>
      <td><b>Occupation: </b>
      </td>
      <td>Teacher</td>
    </tr>

    <tr>
      <td><b>Status: </b>
      </td>
      <td>ACTIVE</td>
    </tr>
  </tbody>
</table>

JS Fiddle demo