You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将嵌套HTML ul/li结构转为JSON?Angular+jQuery求助

问题

我正在开发一款拖拽式表单构建器应用,采用Angular和jQuery技术栈。现有一个主<li>标签,其下包含嵌套的<li>和<ul>标签结构。根据应用需求,需将该结构转换为指定格式的JSON,我尝试使用递归函数但未成功,恳请提供帮助。

原始HTML结构

<li id="mainList" style="list-style: none;">
  <div class="row">
    <div class="col-md-12">
      <ul class="sortable ui-sortable">
        <li data-is-component="true" data-type-text="Text Field" data-type="1" data-element-id="n8b78496-04bd">
          <div class="form-group builder-component mt-1">
            <label style="font-size:smaller" for="exampleFormControlInput1">Text Field</label>
            <input type="email" class="form-control form-control-sm" placeholder="Text Field" disabled="">
          </div>
        </li>
        <li data-is-component="true" data-type-text="Number" data-type="3" data-element-id="nbdbeecb-ff2d">
          <div class="form-group builder-component mt-1">
            <label style="font-size:smaller" for="exampleFormControlInput1">Number</label>
            <input type="email" class="form-control form-control-sm" placeholder="Number" disabled="">
          </div>
        </li>
        <li id="n9cdfd2a-95ea" data-is-component="false" data-type-text="Column 2" data-type="60" data-element-id="n9cdfd2a-95ea">
          <div class="row">
            <div class="col-md-6">
              <ul class="sortable ui-sortable">
                <li data-is-component="true" data-type-text="Choice" data-type="5" data-element-id="n4488d94-bf63">
                  <div class="form-group builder-component mt-1">
                    <label style="font-size:smaller" for="exampleFormControlInput1">Choice</label>
                    <input type="email" class="form-control form-control-sm" placeholder="Choice" disabled="">
                  </div>
                </li>
              </ul>
            </div>
            <div class="col-md-6">
              <ul class="sortable ui-sortable">
                <li data-is-component="true" data-type-text="Select Box" data-type="6" data-element-id="n1179190-213f">
                  <div class="form-group builder-component mt-1">
                    <label style="font-size:smaller" for="exampleFormControlInput1">Select Box</label>
                    <input type="email" class="form-control form-control-sm" placeholder="Select Box" disabled="">
                  </div>
                </li>
                <li data-is-component="true" data-type-text="Date / Time" data-type="7" data-element-id="n2cd4518-633e">
                  <div class="form-group builder-component mt-1">
                    <label style="font-size:smaller" for="exampleFormControlInput1">Date / Time</label>
                    <input type="email" class="form-control form-control-sm" placeholder="Date / Time" disabled="">
                  </div>
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li data-is-component="true" data-type-text="Color" data-type="11" data-element-id="n6103ae8-67e4">
          <div class="form-group builder-component mt-1">
            <label style="font-size:smaller" for="exampleFormControlInput1">Color</label>
            <input type="email" class="form-control form-control-sm" placeholder="Color" disabled="">
          </div>
        </li>
      </ul>
    </div>
  </div>
</li>

期望生成的JSON格式

{
  "id": "mainList",
  "childs": [{
      "id": "n8b78496-04bd",
      "childs": null
    },
    {
      "id": "nbdbeecb-ff2d",
      "childs": null
    },
    {
      "id": "n9cdfd2a-95ea",
      "childs": [
        [{
          "id": "n4488d94-bf63",
          "childs": null
        }],
        [{
          "id": "n1179190-213f",
          "childs": null
        }, {
          "id": "n2cd4518-633e",
          "childs": null
        }]
      ]
    },
    {
      "id": "n6103ae8-67e4",
      "childs": null
    }
  ]
}
解决方案

以下是基于jQuery的递归实现,可精准将目标HTML结构转换为指定格式的JSON:

function convertToJson($element) {
  const result = {
    id: $element.attr('id') || $element.data('element-id'),
    childs: null
  };

  // 处理列容器类型(非组件)
  if ($element.data('is-component') === false) {
    const columns = [];
    // 遍历每个列下的排序列表
    $element.find('.row > [class^="col-md-"]').each(function() {
      const columnItems = [];
      $(this).find('ul.sortable > li').each(function() {
        columnItems.push(convertToJson($(this)));
      });
      columns.push(columnItems);
    });
    result.childs = columns;
  } else {
    // 处理组件类型,检查是否包含子列表
    const childUl = $element.find('ul.sortable');
    if (childUl.length > 0) {
      const childItems = [];
      childUl.find('> li').each(function() {
        childItems.push(convertToJson($(this)));
      });
      result.childs = childItems;
    }
  }

  return result;
}

// 调用示例
const mainList = $('#mainList');
const formJson = convertToJson(mainList);
console.log(JSON.stringify(formJson, null, 2));

代码说明

  • 递归核心逻辑:针对每个<li>元素,根据data-is-component属性区分处理:
    • 非组件(列容器):遍历其下的col-md-*列,将每列内的组件转换为子数组,最终组成二维数组作为childs值。
    • 组件类型:若存在子ul.sortable则递归处理子元素,否则childs设为null。
  • ID匹配规则:优先获取元素的id属性,若不存在则使用data-element-id,完全匹配示例中的ID取值逻辑。
  • Angular适配:如果需要在Angular环境中使用,可将此逻辑封装为服务,或者改用原生JavaScript实现(DOM操作逻辑一致,仅API调用方式不同)。

内容的提问来源于stack exchange,提问作者atalay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 07:41:19