前端 ——xml转json json转xml 实现 mjml 邮件内容转json,json转mjml

⭐前言

大家好,我是yma16,本文分享 前端 ——xml转json json转xml 实现 mjml 邮件内容转json,json转mjml

xml

XML(Extensible Markup Language)是一种类似于 HTML,但是没有使用预定义标记的语言。因此,可以根据自己的设计需求定义专属的标记。这是一种强大将数据存储在一个可以存储、搜索和共享的格式中的方法。最重要的是,因为 XML 的基本格式是标准化的,如果你在本地或互联网上跨系统或平台共享或传输 XML,由于标准化的 XML 语法,接收者仍然可以解析数据。

参考:https://developer.mozilla.org/zh-CN/docs/Web/XML/Parsing_and_serializing_XML
node系列往期文章
node_windows环境变量配置
node_npm发布包
linux_配置node
node_nvm安装配置
node笔记_http服务搭建(渲染html、json)
node笔记_读文件
node笔记_写文件
node笔记_连接mysql实现crud
node笔记_formidable实现前后端联调的文件上传
node笔记_koa框架介绍
node_koa路由
node_生成目录
node_读写excel
node笔记_读取目录的文件
node笔记——调用免费qq的smtp发送html格式邮箱
node实战——搭建带swagger接口文档的后端koa项目(node后端就业储备知识)
node实战——后端koa结合jwt连接mysql实现权限登录(node后端就业储备知识)
node实战——koa给邮件发送验证码并缓存到redis服务(node后端储备知识)

koa系列项目文章
前端vite+vue3结合后端node+koa——实现代码模板展示平台(支持模糊搜索+分页查询)
node+vue3+mysql前后分离开发范式——实现对数据库表的增删改查
node+vue3+mysql前后分离开发范式——实现视频文件上传并渲染

koa-vue性能监控到封装sdk系列文章
性能监控系统搭建——node_koa实现性能监控数据上报(第一章)
性能监控系统搭建——vue3实现性能监控数据展示(第二章)
性能监控计算——封装带性能计算并上报的npm包(第三章)
canvas系列文章
web canvas系列——快速入门上手绘制二维空间点、线、面
webgl canvas系列——快速加背景、抠图、加水印并下载图片
webgl canvas系列——animation中基本旋转、平移、缩放(模拟冒泡排序过程)
前端vue系列文章
vue3 + fastapi 实现选择目录所有文件自定义上传到服务器
前端vue2、vue3去掉url路由“ # ”号——nginx配置
csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板
认识vite_vue3 初始化项目到打包
python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示
让大模型分析csdn文章质量 —— 提取csdn博客评论在文心一言分析评论区内容
前端vue3——html2canvas给网站截图生成宣传海报
前端——html拖拽原理
前端 富文本编辑器原理——从javascript、html、css开始入门
前端老古董execCommand——操作 选中文本 样式
前端如何在30秒内实现吸管拾色器?
前端——原生Selection api操作选中文本 样式、取消样式(解决标签的无限嵌套问题)

⭐定义json结构

object 属性

  • line 行数
  • tagName 标签名称
  • children 子元素
  • attributes 属性
  • content 内容
const json = {
  line: 1,
  includedIn: [],
  tagName: 'mjml',
  children:
   [ {
       line: 2,
       includedIn: [],
       tagName: 'mj-body',
       children:
        [ {
            line: 3,
            includedIn: [],
            tagName: 'mj-section',
            children:
             [ {
                 line: 4,
                 includedIn: [],
                 tagName: 'mj-column',
                 children:
                  [ {
                      line: 5,
                      includedIn: [],
                      tagName: 'mj-text',
                      attributes:
                       { 'font-size': '20px',
                         color: '#F45E43',
                         'font-family': 'helvetica' },
                      content: 'Hello World' } ],
                 attributes: {} } ],
            attributes: {} } ],
       attributes: {} } ],
  attributes: {} }

⭐mjml转json

mjml转成json字符串
把字符串解析成 DOM 树,深度遍历dom转成字符串
示例

const nodeToJSonAction = (node: any, level = 0) => {
  level++;
  const name = node.nodeName?.toLowerCase();
  console.log(name);
  if (
    name &&
    [
      'mjml',
      'mj-body',
      'mj-section',
      'mj-column',
      'mj-text',
      'mj-button',
      'mj-image',
      'mj-divider',
      'mj-social-group',
      'mj-social-element',
      'mj-spacer',
      'mj-navbar',
      'mj-navbar-link',
      'mj-hero',
      'mj-wrapper',
      'mj-raw',
    ].includes(name)
  ) {
    const curConfig: any = {
      line: level,
      includeIn: [],
      tagName: name,
      children: [],
      attributes: {},
    };
    if (name && ['mj-button', 'mj-text'].includes(name)) {
      curConfig.content = node.innerHTML;
    }
    curConfig.line = level;
    // element 配置 span
    if (node.nodeType === Node.ELEMENT_NODE) {
      // 首先,确定那个段落有一些属性
      if (node.hasAttributes()) {
        for (const attr of node.attributes) {
          curConfig.attributes[attr.name] = attr.value;
        }
      } else {
        console.log('null attr');
      }

      for (let i = 0; i < node.childNodes.length; i++) {
        const childConfig = nodeToJSonAction(node.childNodes[i], level);
        console.log('childConfig', childConfig);
        childConfig && curConfig.children.push(childConfig);
      }
    }

    return curConfig;
  }
  return false;
};

export const xmlToJSon = (mjml: string) => {
  const parser = new DOMParser();
  console.log('mjml', mjml);
  const doc = parser.parseFromString(mjml, 'text/html');
  const mjmlNode = doc.body.firstChild;
  return mjmlNode ? nodeToJSonAction(mjmlNode, 0) : {};
};

运行结果

{
  "line": 1,
  "includeIn": [
    
  ],
  "tagName": "mjml",
  "children": [
    {
      "line": 2,
      "includeIn": [
        
      ],
      "tagName": "mj-body",
      "children": [
        {
          "line": 3,
          "includeIn": [
            
          ],
          "tagName": "mj-section",
          "children": [
            {
              "line": 4,
              "includeIn": [
                
              ],
              "tagName": "mj-column",
              "children": [
                {
                  "line": 5,
                  "includeIn": [
                    
                  ],
                  "tagName": "mj-image",
                  "children": [
                    
                  ],
                  "attributes": {
                    "align": "center",
                    "border": "none",
                    "padding-bottom": "30px",
                    "padding": "10px 25px",
                    "src": "http://5vph.mj.am/img/5vph/b/1g86w/0g67t.png",
                    "target": "_blank",
                    "title": "",
                    "width": "180px"
                  }
                },
                {
                  "line": 5,
                  "includeIn": [
                    
                  ],
                  "tagName": "mj-text",
                  "children": [
                    
                  ],
                  "attributes": {
                    "align": "left",
                    "color": "#55575d",
                    "font-family": "Arial, sans-serif",
                    "font-size": "13px",
                    "line-height": "22px",
                    "padding-bottom": "0px",
                    "padding-top": "0px",
                    "padding": "10px 25px"
                  },
                  "content": "\n                            <p style=\"line-height: 18px; margin: 10px 0; text-align: center;font-size:14px;color:#ffffff;font-family:'Times New Roman',Helvetica,Arial,sans-serif\">WOMEN&nbsp; &nbsp; &nbsp; &nbsp;| &nbsp; &nbsp; &nbsp; MEN&nbsp; &nbsp; &nbsp; &nbsp;| &nbsp; &nbsp; &nbsp; KIDS</p>\n                          "
                }
              ],
              "attributes": {
                
              }
            }
          ],
          "attributes": {
            "background-color": "#000000",
            "background-repeat": "no-repeat",
            "text-align": "center",
            "vertical-align": "top"
          }
        },
        {
          "line": 3,
          "includeIn": [
            
          ],
          "tagName": "mj-section",
          "children": [
            {
              "line": 4,
              "includeIn": [
                
              ],
              "tagName": "mj-column",
              "children": [
                {
                  "line": 5,
                  "includeIn": [
                    
                  ],
                  "tagName": "mj-image",
                  "children": [
                    
                  ],
                  "attributes": {
                    "align": "center",
                    "border": "none",
                    "padding-bottom": "0px",
                    "padding-left": "0px",
                    "padding-right": "0px",
                    "padding": "0px 25px",
                    "src": "http://5vph.mj.am/img/5vph/b/1g86w/0696u.jpeg",
                    "target": "_blank",
                    "title": "",
                    "width": "780px"
                  }
                }
              ],
              "attributes": {
                
              }
            }
          ],
          "attributes": {
            "background-color": "#000000",
            "background-repeat": "no-repeat",
            "text-align": "center",
            "vertical-align": "top",
            "padding": "0 0 0 0"
          }
        },
        {
          "line": 3,
          "includeIn": [
            
          ],
          "tagName": "mj-section",
          "children": [
            {
              "line": 4,
              "includeIn": [
                
              ],
              "tagName": "mj-column",
              "children": [
                {
                  "line": 5,
                  "includeIn": [
                    
                  ],
                  "tagName": "mj-text",
                  "children": [
                    
                  ],
                  "attributes": {
                    "align": "left",
                    "color": "#55575d",
                    "font-family": "Arial, sans-serif",
                    "font-size": "13px",
                    "line-height": "22px",
                    "padding-bottom": "5px",
                    "padding-top": "25px",
                    "padding": "10px 25px"
                  },
                  "content": "\n                            <p style=\"line-height: 60px; text-align: center; margin: 10px 0;font-size:55px;color:#fcfcfc;font-family:'Times New Roman',Helvetica,Arial,sans-serif\"><b>Black Friday</b></p>\n                          "
                },
                {
                  "line": 5,
                  "includeIn": [
                    
                  ],
                  "tagName": "mj-text",
                  "children": [
                    
                  ],
                  "attributes": {
                    "align": "left",
                    "color": "#55575d",
                    "font-family": "Arial, sans-serif",
                    "font-size": "13px",
                    "line-height": "22px",
                    "padding-bottom": "20px",
                    "padding-top": "0px",
                    "padding": "10px 25px"
                  },
                  "content": "\n                            <p style=\"line-height: 30px; text-align: center; margin: 10px 0;color:#f5f5f5;font-size:25px;font-family:'Times New Roman',Helvetica,Arial,sans-serif\"><b>Take an&nbsp; extra 50% off</b><br><span style=\"color:#ffffff;font-size:18px;font-family:'Times New Roman',Helvetica,Arial,sans-serif\">Use code SALEONSALE* at checkout</span></p>\n                          "
                }
              ],
              "attributes": {
                
              }
            }
          ],
          "attributes": {
            "background-color": "#000000",
            "background-repeat": "no-repeat",
            "text-align": "center",
            "vertical-align": "top",
            "padding": "0 0 0 0"
          }
        },
        {
          "line": 3,
          "includeIn": [
            
          ],
          "tagName": "mj-section",
          "children": [
            {
              "line": 4,
              "includeIn": [
                
              ],
              "tagName": "mj-column",
              "children": [
                {
                  "line": 5,
                  "includeIn": [
                    
                  ],
                  "tagName": "mj-button",
                  "children": [
                    
                  ],
                  "attributes": {
                    "background-color": "#ffffff",
                    "border-radius": "3px",
                    "font-family": "Times New Roman, Helvetica, Arial, sans-serif",
                    "font-size": "18px",
                    "font-weight": "normal",
                    "inner-padding": "10px 25px",
                    "padding-bottom": "30px",
                    "padding": "10px 25px"
                  },
                  "content": "<span style=\"color:#212020\">Shop Now</span>"
                },
                {
                  "line": 5,
                  "includeIn": [
                    
                  ],
                  "tagName": "mj-text",
                  "children": [
                    
                  ],
                  "attributes": {
                    "align": "left",
                    "color": "#55575d",
                    "font-family": "Arial, sans-serif",
                    "font-size": "13px",
                    "line-height": "22px",
                    "padding-bottom": "0px",
                    "padding-top": "5px",
                    "padding": "10px 25px"
                  },
                  "content": "\n                            <p style=\"line-height: 16px; text-align: center; margin: 10px 0;font-size:12px;color:#ffffff;font-family:'Times New Roman',Helvetica,Arial,sans-serif\">* Offer valid on Allura purchases on 17/29/11 at 11:59 pm. No price adjustments on previous&nbsp;<br><span style=\"color:#ffffff;font-family:'Times New Roman',Helvetica,Arial,sans-serif\">purchases, offer limited to stock. Cannot be combined with any offer or promotion other than free.</span></p>\n                          "
                }
              ],
              "attributes": {
                
              }
            }
          ],
          "attributes": {
            "background-color": "#000000",
            "background-repeat": "no-repeat",
            "text-align": "center",
            "vertical-align": "top",
            "padding-bottom": "40px",
            "padding": "0 0 0 0"
          }
        }
      ],
      "attributes": {
        "background-color": "#F4F4F4",
        "color": "#55575d",
        "font-family": "Arial, sans-serif"
      }
    }
  ],
  "attributes": {
    
  }
}

⭐json转mjml字符串

深度遍历对象,创建虚拟dom


export const xmlToJSon = (mjml: string) => {
  const parser = new DOMParser();
  console.log('mjml', mjml);
  const doc = parser.parseFromString(mjml, 'text/html');
  const mjmlNode = doc.body.firstChild;
  return mjmlNode ? nodeToJSonAction(mjmlNode, 0) : {};
};
const jsonToXmlAction = (jsonConfig: object) => {
  const curTag = jsonConfig.tagName;
  const virDom = document.createElement(curTag);
  if (jsonConfig.attributes) {
    Object.keys(jsonConfig.attributes).forEach((key) => {
      virDom.setAttribute(key, jsonConfig.attributes[key]);
    });
  }
  if (jsonConfig.content) {
    virDom.innerHTML = jsonConfig.content;
  }
  if (jsonConfig.children) {
    for (let i = 0; i < jsonConfig.children.length; ++i) {
      virDom.appendChild(jsonToXmlAction(jsonConfig.children[i]));
    }
  }

  return virDom;
};
export const jsonToXml = (jsonConfig: Object) => {
  if (jsonConfig) {
    return jsonToXmlAction(jsonConfig);
  }
  return '';
};

生成结果:

<mj-body><mj-section><mj-column><mj-image></mj-image><mj-text>
                            <p style="line-height: 18px; margin: 10px 0; text-align: center;font-size:14px;color:#ffffff;font-family:'Times New Roman',Helvetica,Arial,sans-serif">WOMEN&nbsp; &nbsp; &nbsp; &nbsp;| &nbsp; &nbsp; &nbsp; MEN&nbsp; &nbsp; &nbsp; &nbsp;| &nbsp; &nbsp; &nbsp; KIDS</p>
                          </mj-text></mj-column></mj-section><mj-section><mj-column><mj-image></mj-image></mj-column></mj-section><mj-section><mj-column><mj-text>
                            <p style="line-height: 60px; text-align: center; margin: 10px 0;font-size:55px;color:#fcfcfc;font-family:'Times New Roman',Helvetica,Arial,sans-serif"><b>Black Friday</b></p>
                          </mj-text><mj-text>
                            <p style="line-height: 30px; text-align: center; margin: 10px 0;color:#f5f5f5;font-size:25px;font-family:'Times New Roman',Helvetica,Arial,sans-serif"><b>Take an&nbsp; extra 50% off</b><br><span style="color:#ffffff;font-size:18px;font-family:'Times New Roman',Helvetica,Arial,sans-serif">Use code SALEONSALE* at checkout</span></p>
                          </mj-text></mj-column></mj-section><mj-section><mj-column><mj-button><span style="color:#212020">Shop Now</span></mj-button><mj-text>
                            <p style="line-height: 16px; text-align: center; margin: 10px 0;font-size:12px;color:#ffffff;font-family:'Times New Roman',Helvetica,Arial,sans-serif">* Offer valid on Allura purchases on 17/29/11 at 11:59 pm. No price adjustments on previous&nbsp;<br><span style="color:#ffffff;font-family:'Times New Roman',Helvetica,Arial,sans-serif">purchases, offer limited to stock. Cannot be combined with any offer or promotion other than free.</span></p>
                          </mj-text></mj-column></mj-section></mj-body>

⭐inscode代码块

效果演示

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!

sence

👍 点赞,是我创作的动力!

⭐️ 收藏,是我努力的方向!

✏️ 评论,是我进步的财富!

💖 最后,感谢你的阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yma16

感谢支持!共勉!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值