将HTML解析为特定的JSON对象

Parse HTML into a specific JSON object

本文关键字:JSON 对象 HTML      更新时间:2023-09-26

如何从某些HTML创建特定的JSON对象?

示例

这是一个格式非常好的HTML页面(从markdown中呈现)。我想创建页面上各部分的JSON表示。

所以每个"h2"都是一个标题。后面的每个h3、h4或h5都是一个字幕

给定此HTML:

<h2><a href="#charts">Charts</a></h2>
<ul>...</ul>
<h5><a href="#third-party">Third Party</a></h5>
<ul>...</ul>
<h5><a href="#reusable-chart-frameworks">Reusable Chart Frameworks</a></h5>
<ul>...</ul>
<h2><a href="#maps">Maps</a></h2>
<h5><a href="#third-party-1">Third Party</h5>
...

返回此JSON:

[
  {
    "title": {
      "text": "Charts",
      "href": "#charts"
    }
    "subtitles": [
      {
        "text": "Third Party",
        "href": "#third-party"
      },
      {
        "text": "Reusable Chart Frameworks",
        "href": "#reusable-chart-frameworks"
      }
    ]
  },
  {
    "title": {
      "text": "Maps",
      "href": "#maps"
    },
    "subtitles": ]
      "text": "Third Party",
      "href": "#third-party-1"
    ]
  },
  ...
]

我考虑过的解决方案

看来jQuery可以帮上忙。如果这些项是嵌套的,那么很容易执行$('h2').each(...),只需循环遍历每个部分,并将其附加到我的JSON对象中。然而,这里没有嵌套,只有兄弟姐妹。有什么想法吗?

另一个解决方案是映射它:

var mappedJSON = $('h2').map(function() {
  var $selfA = $(this).children('a');
  var subtiles = $(this).nextUntil('h2').filter(':header').children('a').map(function() {
    return {
      "text": $(this).text(),
      "href": $(this).attr('href')
    }
  }).get();
  return {
    "title": {
      "text": $selfA.text(),
      "href": $selfA.attr('href')
    },
    "subtitles": subtiles
  };
}).get();
console.log(mappedJSON);
$('<pre/>').appendTo($('body').empty()).text(JSON.stringify(mappedJSON, null, "'t"));
pre {
  tab-size: 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h2><a href="#charts">Charts</a></h2>
<ul>...</ul>
<h5><a href="#third-party">Third Party</a></h5>
<ul>...</ul>
<h5><a href="#reusable-chart-frameworks">Reusable Chart Frameworks</a></h5>
<ul>...</ul>
<h2><a href="#maps">Maps</a></h2>
<h5><a href="#third-party-1">Third Party</h5>

这里有一个仅依赖于jQuery的.nextUntil()函数的解决方案。

var sections = [];
var eTitles = $('article').find('h2');
$(eTitles).each(function(){
  var section = {
    "title": {
      "text": $(this).text(),
      "href": $(this).find('a').attr('href')
    },
    "subtitles": []
  }
  var eSubtitles = $(this).nextUntil('h2').filter('h3, h4, h5');
  $(eSubtitles).each(function(){
    var subtitle = {
      "text": $(this).text(),
      "href": $(this).find('a').attr('href')
    }
    section.subtitles.push(subtitle);
  });
  sections.push(section);
});