热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

bytejson互转_JSON和HTML之间互转实现

主要实现功能html转json,再由json恢复html可去除style和script标签将行内样式转换为jsobject将class转换为数组形式主要依赖于htmlparser2

主要实现功能html转json,再由json恢复html

可去除 style 和 script 标签

将行内样式转换为 js object

将 class 转换为数组形式

主要依赖于 htmlparser2 ; 这是一个性能优越、功能强大的 html 解析库

ff07d335f79d5e2dbcf5793ab49f633f.png

直接上代码

import { Parser } from "htmlparser2"

const numberValueRegexp = /^\d+$/

const zeroValueRegexp = /^0[^0\s].*$/

const scriptRegexp = /^script$/i

const styleRegexp = /^style$/i

const selfCloseTagRegexp = /^(meta|base|br|img|input|col|frame|link|area|param|embed|keygen|source)$/i

const TAG = 'tag'

const TEXT = 'text'

const COMMENT = 'comment'

/**

* 去除前后空格

*/

export const trim = val => {

return (val || '').replace(/^\s+/, '').replace(/\s+$/, '')

}

/**

* 首字母大写

*/

export const capitalize = word => {

return (word || '').replace(/( |^)[a-z]/, c => c.toUpperCase())

}

/**

* 驼峰命名法/小驼峰命名法, 首字母小写

*/

export const camelCase = key => {

return (key || '').split(/[_-]/).map((item, i) => i === 0 ? item : capitalize(item)).join('')

}

/**

* 大驼峰命名法,首字母大写

*/

export const pascalCase = key => {

return (key || '').split(/[_-]/).map(capitalize).join('')

}

export const isPlainObject = obj => {

return Object.prototype.toString.call(obj) === '[object Object]'

}

/**

* 行内样式转Object

*/

export const style2Object = (style) => {

if (!style || typeof style !== 'string') {

return {}

}

const styleObject = {}

const styles = style.split(/;/)

styles.forEach(item => {

const [prop, value] = item.split(/:/)

if (prop && value && trim(value)) {

const val = trim(value)

styleObject[camelCase(trim(prop))] = zeroValueRegexp.test(val) ? 0 : numberValueRegexp.test(val) ? Number(val) : val

}

})

return styleObject

}

export const toJSON = (html, options) => {

options = Object.assign({ skipStyle: false, skipScript: false, pureClass: false, pureComment: false }, options)

const json = []

let levelNodes = []

const parser = new Parser({

onopentag: (name, { style, class: classNames, ...attrs } = {}) => {

let node = {}

if ((scriptRegexp.test(name) && options.skipScript === true) ||

(styleRegexp.test(name) && options.skipStyle === true)) {

node = false

} else {

if (options.pureClass === true) {

classNames = ''

}

node = {

type: TAG,

tagName: name,

style: style2Object(style),

inlineStyle: style || '',

attrs: { ...attrs },

classNames: classNames || '',

classList: options.pureClass ? [] : (classNames || '').split(/\s+/).map(trim).filter(Boolean),

children: []

}

}

if (levelNodes[0]) {

if (node !== false) {

const parent = levelNodes[0]

parent.children.push(node)

}

levelNodes.unshift(node)

} else {

if (node !== false) {

json.push(node)

}

levelNodes.push(node)

}

},

ontext(text) {

const parent = levelNodes[0]

if (parent === false) {

return

}

const node = {

type: TEXT,

content: text

}

if (!parent) {

json.push(node)

} else {

if (!parent.children) {

parent.children = []

}

parent.children.push(node)

}

},

oncomment(comments) {

if (options.pureComment) {

return

}

const parent = levelNodes[0]

if (parent === false) {

return

}

const node = {

type: COMMENT,

content: comments

}

if (!parent) {

json.push(node)

} else {

if (!parent.children) {

parent.children = []

}

parent.children.push(node)

}

},

onclosetag() {

levelNodes.shift()

},

onend() {

levelNodes = null

}

})

parser.done(html)

return json

}

const setAttrs = (attrs, results) => {

Object.keys(attrs || {}).forEach(k => {

if (!attrs[k]) {

results.push(k)

} else {

results.push(' ', k, '=', '"', attrs[k], '"')

}

})

}

const toElement = (elementInfo, results) => {

switch (elementInfo.type) {

case TAG:

const tagName = elementInfo.tagName

results.push('

if (elementInfo.inlineStyle) {

results.push(' style="', elementInfo.inlineStyle, '"')

}

if (elementInfo.classNames) {

results.push(' class="', elementInfo.classNames, '"')

}

setAttrs(elementInfo.attrs, results)

if (selfCloseTagRegexp.test(tagName)) {

results.push(' />')

} else {

results.push('>')

if (Array.isArray(elementInfo.children)) {

elementInfo.children.forEach(item => toElement(item, results))

}

results.push('', tagName, '>')

}

break;

case TEXT:

results.push(elementInfo.content)

break;

case COMMENT:

results.push("")

break;

default:

// ignore

}

}

export const toHTML = json => {

json = json || []

if (isPlainObject(json)) {

json = [json]

}

const results = []

json.forEach(item => toElement(item, results))

return results.join('')

}

示例

const source = '

测试1
测试2
'

const htmljson = toJSON(source, { skipScript: true, skipStyle: true, pureClass: true, pureComment: true })

const jsonhtml = toHTML(htmljson)

console.log(htmljson)

console.log(jsonhtml)

参数说明

skipScript 过滤 script 标签,默认 false

skipStyle 过滤 style 标签,默认 false

pureClass 去掉 class 属性,默认 false

pureComment 去掉注释,默认 false

备注

htmlparser2 通过 npm i htmlparser2 --save 进行安装即可



推荐阅读
  • JavaScript XML操作实用工具类:XmlUtilsJS技巧与应用 ... [详细]
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • 在 Vue 应用开发中,页面状态管理和跨页面数据传递是常见需求。本文将详细介绍 Vue Router 提供的两种有效方式,帮助开发者高效地实现页面间的数据交互与状态同步,同时分享一些最佳实践和注意事项。 ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
  • 2022年7月20日:关键数据与市场动态分析
    2022年7月20日,本文对当日的关键数据和市场动态进行了深入分析。主要内容包括:1. 关键数据的解读与趋势分析;2. 市场动态的变化及其对投资策略的影响;3. 相关经济指标的评估。通过这些分析,帮助读者更好地理解当前市场环境,为决策提供参考。 ... [详细]
  • 本地存储组件实现对IE低版本浏览器的兼容性支持 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 如何使用ES6语法编写Webpack配置文件? ... [详细]
  • 在Python中,通过实现一个便捷的函数来解码Base64编码的数据,并将其转换为数组形式。该函数能够将Base64字符串解码为字节数组,便于进一步处理。例如,可以使用如下代码片段进行解码:`base64_decode_array('6gAAAOsAAAD')`。这为处理二进制数据提供了高效且简洁的方法。 ... [详细]
  • 利用Java开发功能完备的电话簿应用程序,支持添加、查询与删除操作
    本研究基于Java语言开发了一款功能全面的电话簿应用程序,实现了与数据库的高效连接。该应用不仅支持添加、查询和删除联系人信息,还具备输出最大和最小ID号的功能,并能够对用户输入的ID号进行有效性验证,确保数据的准确性和完整性。详细实现方法可参阅相关文档。 ... [详细]
  • 在处理数据框时,常见的需求是从Excel文件中读取数据,并清除所有字段中的特定字符,如分号。由于列中可能包含多种数据类型,直接操作可能会引发AttributeError。为避免此类错误,建议使用Pandas库中的`applymap`方法,结合自定义函数来实现字符的高效移除。 ... [详细]
  • 本文旨在构建一个JavaScript函数,用于对用户输入的电子邮件地址和密码进行有效性验证。该函数将确保输入符合标准格式,并检查密码强度,以提升用户账户的安全性。通过集成正则表达式和条件判断语句,该方法能够有效防止常见的输入错误,同时提供即时反馈,改善用户体验。 ... [详细]
  • PHP正则表达式主要用于字符串的模式分割、匹配、查找及替换操作。使用正则表达式在某些简单的环境下可能效率不高,因此如何更好的使用PHP正则表达式需要综合考虑。PHP正则表达式的定义 ... [详细]
author-avatar
zhuzhuxiaozhuzhu
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有