Transform JavaScript XML DOM Object into an Object with a specific structure

After parsing a large XML DOM Object using jQuery's $.parseXML function, I have a JavaScript DOM Object. My goal is to create a regular JavaScript Object with a specific structure:

{
    name: 'my_tree',
    children: [
        { name: 'hello' },
        { name: 'wat' },
        {
            name: 'child_folder',
            children: [
                {
                    name: 'child_folder',
                    children: [
                        { name: 'hello' },
                        { name: 'wat' }
                    ]
                },
                { name: 'hello' },
                { name: 'wat' },
                {
                    name: 'child_folder',
                    children: [
                        { name: 'hello' },
                        { name: 'wat' }
                    ]
                }
            ]
        }
    ]
}

The original XML structure would resemble something like the following:

<my_tree>
    <hello></hello>
    <wat></wat>
    <child_folder>
        <child_folder>
            <hello></hello>
            <wat></wat>
        </child_folder>
        <hello></hello>
        <wat></wat>
        <child_folder>
            <hello></hello>
            <wat></wat>
        </child_folder>
    </child_folder>
</my_tree>

Although I attempted to accomplish this with code snippet provided below, it did not yield the desired outcome:

function xmlDomToObject(domObject) {
    var result = {children: []};
    for (var i = 0; i < domObject.length; i++) {
        if (domObject[i].nodeName == "#text") {
            continue;
        }

        result['name'] = domObject[i].nodeName;
        result['children'].push(xmlDomToObject(domObject[i].childNodes));
    }

    return result;
}

var xmlObject = xmlDomToObject(xmlDomObject.childNodes);

Answer №1

Here is a potential method to consider. Utilizing the children property, instead of childNodes, allows for excluding text nodes and focusing solely on Elements:

function analyzeXml(node) {
  const el = {
    name: node.nodeName
  };

  const children = Array.prototype.map.call(node.children, analyzeXml);
  // ES6: const children = [...node.children].map(analyzeXml);
  if (children.length) {
    el.children = children;
  }

  return el;
}

You may implement this as is, just ensure to pass the documentElement property of the result from $.parseXML - rather than the result itself.

const xmlStr = `<my_tree>
    <hello></hello>
    <wat></wat>
    <child_folder>
        <child_folder>
            <hello></hello>
            <wat></wat>
        </child_folder>
        <hello></hello>
        <wat></wat>
        <child_folder>
            <hello></hello>
            <wat></wat>
        </child_folder>
    </child_folder>
</my_tree>`;

const xml = $.parseXML(xmlStr);
const parsed = analyzeXml(xml.documentElement);

console.log(parsed);

function analyzeXml(node) {
  const el = {
    name: node.nodeName
  };

  // const children = [...node.children].map(analyzeXml);
  const children = Array.prototype.map.call(node.children, analyzeXml);
  if (children.length) {
    el.children = children;
  }
 
  return el;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When traversing across different child elements, the MouseEvent.offsetX/Y values get reset to 0

Check out this interactive example. The demonstration includes a main div with 3 child divs. A click event is triggered on the main div, but instead of displaying alerts with the mouse position relative to the parent div as expected, it shows the position ...

What is the best approach to setting up dynamic Vue routing?

I am working on implementing dynamic routing for the website that relies on changes in agreements. Here is the path tree I have set up: const routes = [ { path: "/", redirect: "/home", component: DefaultLayou ...

React-file-viewer shrinks any document to a compact size

I have been searching extensively for information on how to adjust file sizing in react-file-viewer without any success. My objective is to utilize the react-file-viewer to allow users to click on a filename hyperlink and open the file (be it an image, do ...

Custom time selector does not automatically set the default value

After creating two inputs where one represents hours and the other minutes, clicking on edit should display the total time in seconds. The original time for editing should remain unchanged until you choose to save it. Here is the link to the code: https:// ...

Bootbox Dialog Form

Looking to implement a functionality where a Bootbox dialog pops up with an "OK" button. Upon clicking the "OK" button, it should initiate a POST request, sending back the ID of the message to acknowledge that the user has read it. The Bootbox dialog fun ...

Confused about the path

After completing an AngularJS lesson, I encountered an issue where Angular was not able to understand links to the details page, such as template/1, when clicking on a link from the browser. However, when manually entering the URL in the address bar of the ...

Troubleshooting VueJS, Electron, and Webpack integration with Hot Reload feature

I have been immersed in a new project that involves utilizing Electron, VueJS, and Webpack for HMR functionality. Unfortunately, I am encountering difficulties with the Hot Module Replacement feature not working as expected. Here is my current configurati ...

This method or property is not supported by the object - How to call an Applet in Internet Explorer 9

cmd > java -version Java Version : "1.7.0_11" (Updated) Java(TM) SE Runtime Environment (build 1.7.0_11-b21) Java HotSpot(TM) Client VM (build 23.6-b04, mixed mode, sharing) browsers = IE7,IE8,IE9 (The functionality works smoothly in Google Chrome and ...

The uncertainty surrounding the usage of checkboxes in D3.js

I am faced with the challenge of adding checkboxes to multiple groups within an SVG, each containing a circle and text element. I have attempted to accomplish this by using D3 to append foreignObject tags and then add checkboxes to each group. The code I h ...

Setting predefined data in an HTML field from XML within the Odoo platform

In the model.py file of my project, I have defined an HTML field as follows: from odoo import models, fields class TestModel(models.model): _name = 'test.model' content = fields.HTML() To display the data from this model, I have used &l ...

Transferring information from one page to the next

How can I efficiently transfer a large amount of user-filled data, including images, between pages in Next.js? I've searched through the Next.js documentation, but haven't found a solution yet. ...

npm is facing difficulties while trying to install the scrypt package. It is prompting the requirement

When attempting to run a blockchain application, I encountered an error message that reads: npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! [email protected] install: node-gyp rebuild npm ERR! Exit status 1 npm E ...

The text/font-weight of the header button is mysteriously shifting without warning

While creating a header for my webpage, I encountered an issue where the text family was changing when the dropdown menu was launched in Safari 8. Curiously, this behavior did not occur when using Chrome to launch the jQuery function. Even after attempting ...

Separating stylesheets, head, and other elements in a curl response

After successfully using curl to retrieve an external site, I noticed that the results were interfering with my own content. The CSS from the external site was affecting my webpage's layout and z-index values were conflicting. I am seeking a solution ...

Express Session doesn't remove the variable assigned

While developing a web application using Node Express, I encountered a simple issue in my new project. Despite setting a session variable to null, the old session data is still being called. Seeking assistance to resolve this issue. I utilized express-ses ...

Is there a way for me to move the dot icon along the dotline?

Here is the code snippet: jsFiddle I have successfully implemented a click event to change the style of selected dots in dotline. Now, my query is : How can I enable dragging functionality for the dot icon within dotline? Your assistance on this matte ...

Why does starting up the Firebase emulators trigger the execution of one of my functions as well?

Upon running firebase emulators:start --only functions,firestore, the output I receive is as follows: $ firebase emulators:start --only functions,firestore i emulators: Starting emulators: functions, firestore ⚠ functions: The following emulators are ...

Errors during the compilation of Webgl shaders in the Google Chrome browser

Currently, I am in the process of learning three.js by following this tutorial: . Despite the tutorial working well, I have encountered errors in my own code which seem like this: ERROR: 0:26: 'nuniform' : syntax error Three.js:325 precision hi ...

AngularJS: Utilizing nested ng-repeats for dynamic data rendering

Currently, I am utilizing the ng-repeat directive in conjunction with the ng-repeat-start/ng-repeat-end options. Within the main loop, there is an additional inner ng-repeat. However, the problem lies in the fact that the outer ng-repeat-start declaration ...

Converting RowDataPacket to an array in Node.js and MySQL API, learn how to convert a RowDataPacket from the MySQL API into an array

Hello, I need assistance with converting my row data packet into an array of arrays or nested arrays. Please provide code snippet below: router.get('/getPosts/:user_id', (req, res, next) => { connection.query('SELECT * FROM files WHERE ...