0

I've been Googling for this for last 2 days. I couldn't get it done perfectly.

I assume, this belongs or can be done by some template engines, but.. I was not able to find that so-called engine.

I have this JSON array and I'd like to parse it back or convert it to plain HTML to output it to the browser.

[
  {
    "tag": "figure",
    "children": [
      {
        "tag": "div",
        "attrs": {
          "class": "fiwrapper"
        },
        "children": [
          {
            "tag": "img",
            "attrs": {
              "src": "/media/images/5cbd41bd7c566057f5e6a875.jpeg"
            }
          }
        ]
      },
      {
        "tag": "figcaption",
        "children": [
          ""
        ]
      }
    ]
  },
  {
    "tag": "p",
    "children": [
      {
        "tag": "br"
      }
    ]
  },
  {
    "tag": "figure",
    "children": [
      {
        "tag": "div",
        "attrs": {
          "class": "fiwrapper"
        },
        "children": [
          {
            "tag": "img",
            "attrs": {
              "src": "/media/images/5cbd45286c7210581c5563ba.jpeg"
            }
          }
        ]
      },
      {
        "tag": "figcaption",
        "children": [
          ""
        ]
      }
    ]
  },
  {
    "tag": "p",
    "children": [
      {
        "tag": "br"
      }
    ]
  },
  {
    "tag": "p",
    "children": [
      "Cool Stuff.."
    ]
  }
]

Help is more than appreciated..

2
  • You would want to convert the array into some kind of token array first. Then you can turn that into a string. Commented Apr 22, 2019 at 15:22
  • What have you tried? Please edit your question to include the code you've written so far. Commented Apr 22, 2019 at 15:24

1 Answer 1

1

All you need to do this is a recursive parser that will parse the json from top to bottom.

here is the parser to do so in javascript and the same logic can be translated into any other language as well.

const getAttrMap = (attr) => attr ? Object.keys(attr).reduce((acc, curr) => `${acc} ${curr}="${attr[curr]}"`, '') : '';

function parseArr(arr) {
    return arr.map(curr => parser(curr)).join('\n');
}

function parser(obj) {    
    if (typeof obj === 'object') {
        if (!obj.children) {
            return `<${obj.tag} ${getAttrMap(obj.attrs)}/>`
        }
        return `<${obj.tag} ${getAttrMap(obj.attrs)}>${
            obj.children instanceof Array ? parseArr(obj.children) : parser(obj.children)}</${obj.tag}>`;
    }
    if (!obj) {
        return '';
    }
    return obj;
}

// usage
parseArr(inputJson);

Explanation

If we know how to translate one block we can translate each block recursively. To parse one block the logic is simple.

<${obj.tag} ${getAttrMap(obj.attrs)}>CHILD</${obj.tag}>

This will convert an object into an HTML tag but what if CHILD is another tag itself? simple we call the same parser function again, however in this case CHILD can be an array (multiple tags) or a single one based of that we either call parseArr or parser. In cases where children are not provided, we simply return the empty string.

Output

<figure ><div  class="fiwrapper"><img  src="/media/images/5cbd41bd7c566057f5e6a875.jpeg"></img></div>
<figcaption ></figcaption></figure>
<p ><br ></br></p>
<figure ><div  class="fiwrapper"><img  src="/media/images/5cbd45286c7210581c5563ba.jpeg"></img></div>
<figcaption ></figcaption></figure>
<p ><br ></p>
<p >Cool Stuff..</p>``



Sign up to request clarification or add additional context in comments.

1 Comment

Well done.. Very well done! with a bit more enhancing.. I got the perfect function. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.