DEV Community

Karol Bajko
Karol Bajko

Posted on

Modifying JSON - easy or difficult?

You probably have many technical challenges to face in your work. Some of them are time-consuming, others fast to solve. Sometimes you face problems very well understandable and potentially easy to solve … but in the end, you see that plenty of hours were consumed to find a solution that should take less than an hour.

So… how about modifying JSON? Is it easy or difficult in Ruby (& Rails)?

Let's assume we have a simple structure with HTML fragments within:

{
  "a": {
    "b": [
      {
        "c": "<span id=\"head\"></span>"
      },
      {
        "d": "<span id=\"body\"></span>"
      }
    ],
    "e": "#ffffff"
  },
  "f": "<span id=\"footer\"></span>",
  "g": 123
}
Enter fullscreen mode Exit fullscreen mode

and we have a list of variables like:

head = "Hey John!"
body = "I invite you to my Birthday party!"
footer = "Best regards."
Enter fullscreen mode Exit fullscreen mode

Our goal is to find specific DOM fragments within that tree and inject text. Other values cannot be changed. So we'll end with something like that.

{
  "a": {
    "b": [
      {
        "c": "<span id=\"head\">Hey John!</span>"
      },
      {
        "d": "<span id=\"body\">I invite you to my Birthday party!</span>"
      }
    ],
    "e": "#ffffff"
  },
  "f": "<span id=\"footer\">Best regards.</span>",
  "g": 123
}
Enter fullscreen mode Exit fullscreen mode

Looks like the solution is quite simple. You can convert it to hash and use the deep_transform_values method in combination with the nokogiri gem.

hash.deep_transform_values { |value|
  if value.is_a?(String)
    html = Nokogiri::HTML5.fragment(value)

    head_node = html.at_css("#head")
    body_node = html.at_css("#body")
    footer_node = html.at_css("#footer")

    head_node&.inner_html = head
    body_node&.inner_html = body
    footer_node&.inner_html = footer

    html.to_s
  else
    value
  end
}
Enter fullscreen mode Exit fullscreen mode

… and that's all.

Top comments (0)