javascript - 如何从以下 xml 制作层次结构数组?

标签 javascript arrays xml hierarchy

我有一个 XML 数据,我需要将其转换成一个数组,XML 数据具有层次结构,但它处于同一级别,因此需要识别问题。我在下面给出了预期的输出数组以及我的工作。

以下XML 数据 可以有多个层次结构

<data>
<GROUP NAME="Sundry Debtors">
    <PARENT></PARENT>
</GROUP>
<GROUP NAME="Sundry Debtors-Pune">
    <PARENT>Sundry Debtors</PARENT>
</GROUP>
<GROUP NAME="Sundry Debtors-Akurdi">
    <PARENT>Sundry Debtors-Pune</PARENT>
</GROUP>
<GROUP NAME="Sundry Creditors">
    <PARENT></PARENT>
</GROUP>
<GROUP NAME="Sundry Creditors-Pune">
    <PARENT>Sundry Creditors</PARENT>
</GROUP>
</data>

以下是上述 xml 数据的预期输出

let arr = [
  {
    name: "Sundry Debtors",
    data: [{ name: "Sundry Debtors-Pune", data: [{ name: "Sundry Debtors-Akurdi", data: [] }] }]
  },
  { name: "Sundry Creditors", data: [{ name: "Sundry Creditors-Pune", data: [] }] }
];

以下是我到目前为止尝试过的内容

<!DOCTYPE html>
<html>
  <title>test</title>
  <script>
    //Desired output
    let arr = [
      {
        name: "Sundry Debtors",
        data: [{ name: "Sundry Debtors-Pune", data: [{ name: "Sundry Debtors-Akurdi", data: [] }] }]
      },
      { name: "Sundry Creditors", data: [{ name: "Sundry Creditors-Pune", data: [] }] }
    ];
    let text =
      '<data><GROUP NAME="Sundry Debtors"><PARENT></PARENT></GROUP><GROUP NAME="Sundry Debtors-Pune"><PARENT>Sundry Debtors</PARENT></GROUP><GROUP NAME="Sundry Debtors-Akurdi"><PARENT>Sundry Debtors-Pune</PARENT></GROUP><GROUP NAME="Sundry Creditors"><PARENT></PARENT></GROUP><GROUP NAME="Sundry Creditors-Pune"><PARENT>Sundry Creditors</PARENT></GROUP></data>';
    let parser = new DOMParser();
    let xml = parser.parseFromString(text, "text/xml");
    var node = xml.getElementsByTagName("GROUP");
    let total = 0;
    let levels = [];
    let level = 0;
    let hirarchy = [];
    total = node.length;
    function getChilds(parent) {
      let arr = [];
      for (let j = 0; j < total; j++) {
        let e = node[j];
        let grpName = e.getAttribute("NAME");
        let parentCount = e.getElementsByTagName("PARENT")[0].childNodes.length;
        if (parentCount > 0) {
          let parentName = e.getElementsByTagName("PARENT")[0].childNodes[0].nodeValue;
          if (parentName === parent) {
            arr.push(grpName);
          }
        }
      }
      return arr;
    }
    function getParent(child) {
      let arr = [];
      for (let k = 0; k < total; k++) {
        let e = node[k];
        let grpName = e.getAttribute("NAME");
        if (grpName === child) {
          let parentCount = e.getElementsByTagName("PARENT")[0].childNodes.length;
          let parentName = parentCount > 0 ? e.getElementsByTagName("PARENT")[0].childNodes[0].nodeValue : undefined;
          return parentName;
        }
      }
    }
    function findNode(array, nodename) {
      for (let j = 0; j < array.length; j++) {
        const e = array[j];
        if (e.name === nodename) {
          return e;
        } else {
          if (e.data.length > 0) {
            //console.log(e.data, nodename);
            return findNode(e.data, nodename);
          } else {
            return null;
          }
        }
      }
    }
    let new_h = [];
    for (i = 0; i < total; i++) {
      let e = node[i];
      let grpName = e.getAttribute("NAME");
      let childs = getChilds(grpName);
      let parent = getParent(grpName);
      //console.log(i, grpName, " --->", childs, parent);
      if (!parent) {
        let arr = { name: grpName, data: [] };
        new_h.push(arr);
      } else {
        let arr = findNode(new_h, parent);
        if (arr) {
          arr.data.push({ name: grpName, data: [] });
        } else {
        }
      }
    }
    console.log(new_h);
  </script>
</html>

最佳答案

尝试以下代码。

<!DOCTYPE html>
<html>
  <title>test</title>
  <script>
    let expected_output_array = [
      {
        name: "Sundry Debtors",
        data: [{ name: "Sundry Debtors-Pune", data: [{ name: "Sundry Debtors-Akurdi", data: [] }] }]
      },
      { name: "Sundry Creditors", data: [{ name: "Sundry Creditors-Pune", data: [] }] }
    ];
    let text =
      '<data><GROUP NAME="Sundry Debtors"><PARENT></PARENT></GROUP><GROUP NAME="Sundry Debtors-Pune"><PARENT>Sundry Debtors</PARENT></GROUP><GROUP NAME="Sundry Debtors-Akurdi"><PARENT>Sundry Debtors-Pune</PARENT></GROUP><GROUP NAME="Sundry Creditors"><PARENT></PARENT></GROUP><GROUP NAME="Sundry Creditors-Pune"><PARENT>Sundry Creditors</PARENT></GROUP></data>';
    let parser = new DOMParser();
    let xml = parser.parseFromString(text, "text/xml");
    var node = xml.getElementsByTagName("GROUP");
    let total = 0;
    total = node.length;
    function getChilds(parent) {
      let arr = [];
      for (let j = 0; j < total; j++) {
        let e = node[j];
        let grpName = e.getAttribute("NAME");
        let parentCount = e.getElementsByTagName("PARENT")[0].childNodes.length;
        if (parentCount > 0) {
          let parentName = e.getElementsByTagName("PARENT")[0].childNodes[0].nodeValue;
          if (parentName === parent) {
            arr.push(grpName);
          }
        }
      }
      return arr;
    }
    function getParent(child) {
      let arr = [];
      let total = node.length;
      for (let k = 0; k < total; k++) {
        let e = node[k];
        let grpName = e.getAttribute("NAME");
        if (grpName === child) {
          let parentCount = e.getElementsByTagName("PARENT")[0].childNodes.length;
          let parentName = parentCount > 0 ? e.getElementsByTagName("PARENT")[0].childNodes[0].nodeValue : undefined;
          return parentName;
        }
      }
    }
    function findNodeSequential(array, nodename) {
      for (let k = 0; k < array.length; k++) {
        const e = array[k];
        if (e.name === nodename) {
          return e;
        } else {
          if (e.data.length > 0) {
            return findNodeSequential(e.data, nodename);
          } else {
            return null;
          }
        }
      }
    }
    function findNode(array, nodename) {
      for (let j = 0; j < array.length; j++) {
        let e = array[j];
        if (e.name === nodename) {
          return e;
        } else {
          if (e.data.length > 0) {
            e = findNodeSequential(e.data, nodename);
            if (e !== null) {
              return e;
            }
          }
        }
      }
    }
    let h = [];
    for (let i = 0; i < total; i++) {
      let e = node[i];
      let grpName = e.getAttribute("NAME");
      let childs = getChilds(grpName);
      let parent = getParent(grpName);
      if (!parent) {
        let arr = { name: grpName, data: [] };
        h.push(arr);
      }
    }
    for (let l = 0; l < total; l++) {
      let e = node[l];
      let grpName = e.getAttribute("NAME");
      let childs = getChilds(grpName);
      let parent = getParent(grpName);
      if (parent) {
        let arr = findNode(h, parent);
        if (arr) {
          arr.data.push({ name: grpName, data: [] });
        } else {
        }
      }
    }
    console.log("Expected output:", expected_output_array);
    console.log("Output: ", h);
  </script>
</html>

关于javascript - 如何从以下 xml 制作层次结构数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59465351/

相关文章:

java - 用 JPanel 数组制作棋盘

arrays - 属性数组的总和

java - 如何用 Java 读取 .Net 服务生成的 XML

java - 启动画面不会显示,只有空白区域

Android 使用布局作为模板创建多个布局实例

javascript - React 类组件在重新渲染时更新类变量的值,但不更新函数组件

javascript - Chrome 上的 Javascript 中的日期验证

javascript - 如何选择最接近随机数的整数?

javascript - 过滤电影列表 JavaScript

c# - C#中的数组如何部分实现IList<T>?