Convert HTML element to a JSON object

Here is an example of an HTML element:

<div class='myparent'>
    <div>
        <div class="pdp-product-price">
            <span> 650 rupees</span>
            <div class="origin-block">
               <span> 1,500 rupees</span>
               <span>-57%</span>
            </div>
        </div>
    </div>
</div>

I am looking to generate a JSON representation of the 'myparent' div.

{
    "div": {
        "div": {
            "div": {
                "span": {},
                "div": {
                    "span": {},
                    "span": {}
                }
            }
        }
     }
}   

Do you know if it's possible to achieve this using JavaScript?

Answer №1

To access the subtree, utilize the children property of the HTMLElement.

Next, recursively iterate over the parent to retrieve the subtree.

Note: Avoid assigning multiple values with the same key; instead, use an index when assigning a subtree like so:

  "div": {
     "span_1": {},
     "span_2": {},
  }

Check out the snippet below for further insight:

const parent = document.getElementById('parent')

const tree = {};


const getTree = (elem) =>{
   const subtree = {};
   for(let child of elem.children){
       subtree[child.tagName.toLowerCase()] = getTree(child)
   }
   return subtree;
}

tree[parent.tagName.toLowerCase()] = getTree(parent);

console.log(tree);
<div id="parent" class='myparent'>
  <div>
    <div class="pdp-product-price">
      <span> 650 rupees</span>
      <div class="origin-block">
        <span> 1,500 rupees</span>
        <span>-57%</span>
      </div>
    </div>
  </div>
</div>

Answer №2

A recursive function is utilized to construct the json data in a way that prevents any potential issues with duplicate keys. To achieve this, a unique identifier :n is appended to each key, where n represents the index of the element.

function htmlToObject(targetElement) {
  return Array
    .from(targetElement.children)
    .reduce((acc, cur, i) => {
      acc[`${cur.tagName}:${i}`.toLowerCase()] = htmlToObject(cur);
      return acc;
    }, {});
}

const startElement = document.getElementsByClassName("myparent")[0];

const res = {
  [startElement.tagName.toLowerCase()]: htmlToObject(startElement)
};

console.log(res);
<div class='myparent'>
  <div>
    <div class="pdp-product-price">
      <span> 650 rupees</span>
      <div class="origin-block">
        <span> 1,500 rupees</span>
        <span>-57%</span>
      </div>
    </div>
  </div>
</div>

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

Tips to prevent the return of undefined when a condition is not satisfied

I'm currently working on a react app and I have an array of objects (items) that I want to iterate over in order to display each object based on its index. I am using useState to set the index, which is updated when the user clicks a button. const ...

Building an OData WebAPI in C# to Retrieve a Collection of Items through a POST

Hello, I find myself in need of assistance. I am currently working on a small WebApi Program and have encountered an issue while unit testing. During my unit testing, I realized that I am unable to send a list of elements to my post method. Let's b ...

Display all y-axis values in the tooltip using HighCharts

I utilized a chart example from http://www.highcharts.com/demo/column-stacked When you hover the mouse over a column, it displays the value of the y axis being hovered and the total value. I am interested in having the tooltip show the values of all 3 y ...

"Encountering a 404 error on newly published content, post build phase, with the integration of Next

My main objective is to enable the addition of new posts to the CMS (Sanity.io) post-build, and have the website display the received data on a designated slug through dynamic routes. While everything functions smoothly in the development environment, I e ...

What is the most effective method for incorporating multi-line breadcrumb links in a React application?

I am currently working on implementing a multiline breadcrumb link feature for mobile and tablet devices. As users navigate through multiple folders, I need to handle scenarios where the number of links exceeds the maximum allowed in the breadcrumb contain ...

Restarting an Angular app is necessary once its HTML has been updated

I've encountered an interesting challenge with an application that combines MVC and Angular2 in a not-so-great way. Basically, on the Index page, there's a partial view loading the Angular app while also including all the necessary JavaScript li ...

Warning: Attempting to modify a property that is not defined - 'action'

My code includes a datatable and an alert that pops out. The datatable functions properly with or without the alert, but the alert does not work well when combined with the datatable. Could this be causing a conflict in the code? An error message indicates ...

The beauty of crafting intricate forms with Angular's reactive nested

In my Angular project, I am exploring the concept of nesting multiple reactive forms within different components. For instance, I have a component called NameDescComponent that includes a form with two inputs - one for name and one for description, along ...

Any tips or hacks for successfully implementing vw resizing on the :before pseudo-element in webkit browsers?

When using vw sizes on webkit browsers, a well-known bug can occur where they do not update when the window is resized. The typical workaround for this issue has been to employ javascript to force a redraw of the element by reassigning the z-index upon res ...

Paper.js - generate a collection of movable shapes

I am attempting to use paper.js to create draggable shapes where the index of each shape is provided during dragging. Unfortunately, I keep encountering an error that says "Uncaught TypeError: Cannot read property 'position' of undefined". If a ...

Baconjs exclusively retrieves the final debounce value

Below is a code snippet that showcases my current implementation: let watcher; const streamWatcher = bacon.fromBinder(sink => { watcher = chokidar.watch(root, { ignored: /(^|[\/\\])\../ }); watcher.on('all&a ...

The node server is experiencing difficulties connecting to the mysql database, resulting in a timed out connection error at Connection._handleConnectTimeout

Having trouble establishing a connection with the mysql database. Every time I attempt to start the node server, it keeps throwing a database connection error. The specific error message is as follows: connect ETIMEDOUT at Connection._handleConnectTimeou ...

Is there a way to attach a model to an Angular directive?

Currently, I am implementing angular's typeahead functionality using the following resource: I have created a directive with the following template: <div> <input type="text" ng-model="user.selected" placeholder="Ty ...

Tips for utilizing the Toggle Slider JS functionality

I'm attempting to change a value using a slider in HTML, here is my approach: html file : <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script scr="./scripts.js" ...

group items into ranges based on property of objects

I've been grappling with this issue for far too long. Can anyone provide guidance on how to tackle the following scenario using JavaScript? The dataset consists of objects representing a date and a specific length. I need to transform this list into a ...

Error encountered when attempting to retrieve token from firebase for messaging

I am currently working on implementing web push notifications using Firebase. Unfortunately, when attempting to access messaging.getToken(), I encounter an error stating "messaging is undefined." Below is the code snippet I am utilizing: private messaging ...

Performing calculations while transferring information via Mongoose to the MongoDb database

Seeking assistance with calculating a user's BMI and storing it in my MongoDB atlas database. The BMI will be determined based on the height and weight provided by the users. I have created a Mongoose Schema to define the necessary functions, but I am ...

Utilize the Tab key in Textarea fields to insert a tab character ( ) instead of navigating to the

My current issue involves utilizing an HTML textarea named userInput. Whenever I press the tab key, it simply shifts focus to the next element instead of inserting a tab character or some spaces within the textarea. Is there a way for me to configure the ...

Implementing setInterval() leads to the dynamic alteration of images

I've created Marquees using CSS animations and a countdown timer. The Marquees display 100 random images that move from left to right and right to left. However, when the countdown timer decreases, the images in the Marquee change but the scrolling co ...

display the information stored within the sports attribute using React

I am attempting to display the values stored in the sports property. So, I inserted a console log within the sports property. However, an error is being thrown: Syntax error: C:/codebase/src/containers/sports.js: Unexpected token, expec ...