如何从以下xml中创建层次结构数组?

问题描述 投票:1回答:1

我有一个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>
javascript arrays xml hierarchy
1个回答
1
投票

我希望这会有所帮助,

var convert = require('xml-js');
let xmlString = `<?xml version="1.0" encoding="UTF-8"?>
<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>`;

/* convert xml to json object */
result = convert.xml2js(xmlString, {compact: true, spaces: 4});

let exists_arr = [];

var group = result.data.GROUP;

function fchild(par) {

   let final = [];

   for (var i = 0; i <= group.length - 1; i++) {

      let {_attributes, PARENT} = group[i];

      /* checking if its the top-most level group (Object.keys(PARENT).length == 0 then its top level group) and does not exist in exists_arr */
      if( Object.keys(PARENT).length == 0 && par == false && !exists_arr.includes(_attributes.NAME)){

        /* push to exists_arr */
        exists_arr.push(_attributes.NAME);

        /* push to final array, also calling the function in recurtion to find the children of the current */
        final.push({ name:_attributes.NAME, data:fchild(_attributes.NAME)});

      } 
      else if(par == PARENT._text && !exists_arr.includes(_attributes.NAME) ){
       /* entering if 'par' value matches with parent text & does not exist in exists_arr */

        /* push to exists_arr */
        exists_arr.push(_attributes.NAME);

        /* push to final array, also calling the function in recurtion */
        final.push({ name:_attributes.NAME, data:fchild(_attributes.NAME)});

      }  
   }
   return final;
}

console.log(JSON.stringify(fchild(false)));
© www.soinside.com 2019 - 2024. All rights reserved.