0

I have a txt file which have the format shown below and the Key strings are not in quotes. How can I convert into a JSON using python?

name {
  first_name: "random"
}
addresses {
  location {
    locality: "India"
    street_address: "xyz"
    postal_code: "300092"
    full_address: "street 1 , abc,India"
  }
}
projects {
  url: "www.githib.com"
}
Nish
  • 13
  • 2
  • 5
  • Hint : Use `json` module. – Abdul Niyas P M Apr 25 '18 at 06:40
  • Your JSON is not valid – TerryA Apr 25 '18 at 06:42
  • 1
    @TerryA I think the OP realizes that the text file isn't JSON. They want to know how to convert it to JSON. – PM 2Ring Apr 25 '18 at 06:43
  • @ABDULNIYASPM The json module won't handle that data without some pre-processing. – PM 2Ring Apr 25 '18 at 06:44
  • @Rakesh That dupe target isn't relevant here. The OP's data isn't actually JSON. – PM 2Ring Apr 25 '18 at 07:06
  • @PM2Ring Thanks for the clarification i just edited that in my question.And yes guys the Key values are not in quotes and hence i needed them to be converted into JSON. Any help on how to do that will be greatly appreciated.Thanks in advance. – Nish Apr 25 '18 at 07:30
  • @Nish I've re-opened your question, and posted some code. Generally, it's expected that you post your own attempt at writing code for your problem. I guess in this case you didn't know where to start, but even then you should write _something_ relevant and explain where you're stuck. – PM 2Ring Apr 25 '18 at 07:45

2 Answers2

0

Assuming your data as,

{
    'addresses': {
        'location': {
            'full_address': 'street 1 , abc,India',
            'locality': 'India',
            'postal_code': '300092',
            'street_address': 'xyz'
        }
    },
    'name': {
        'first_name': 'random'
    },
    'projects': {
        'url': 'www.githib.com'
    }
}

Use json.dumps to convert dict to json

In [16]: import json

In [17]: data
Out[17]:
{'addresses': {'location': {'full_address': 'street 1 , abc,India',
   'locality': 'India',
   'postal_code': '300092',
   'street_address': 'xyz'}},
 'name': {'first_name': 'random'},
 'projects': {'url': 'www.githib.com'}}

In [18]: json.dumps(data)
Out[18]: '{"name": {"first_name": "random"}, "projects": {"url": "www.githib.com"}, "addresses": {"location": {"postal_code": "300092", "full_address": "street 1 , abc,India", "street_address": "xyz", "locality": "India"}}}'

In [19]:
Nishant Nawarkhede
  • 8,234
  • 12
  • 59
  • 81
  • 1
    But the OP's data file doesn't look like your input data. In particular, the key strings aren't quoted. – PM 2Ring Apr 25 '18 at 06:54
0

There's no simple way in the standard library to convert that data format to JSON, so we need to write a parser. However, since the data format is fairly simple that's not hard to do. We can use the standard csv module to read the data. The csv.reader will handle the details of parsing spaces and quoted strings correctly. A quoted string will be treated as a single token, tokens consisting of a single word may be quoted but they don't need to be.

The csv.reader normally gets its data from an open file, but it's quite versatile, and will also read its data from a list of strings. This is convenient while testing since we can embed our input data into the script.

We parse the data into a nested dictionary. A simple way to keep track of the nesting is to use a stack, and we can use a plain list as our stack.

The code below assumes that input lines can be one of three forms:

  1. Plain data. The line consists of a key - value pair, separated by at least one space.
  2. A new subobject. The line starts with a key and ends in an open brace {.
  3. The end of the current subobject. The line contains a single close brace }

import csv
import json

raw = '''\
name {
  first_name: "random"
}
addresses {
  location {
    locality: "India"
    street_address: "xyz"
    postal_code: "300092"
    full_address: "street 1 , abc,India"
  }
}
projects {
  url: "www.githib.com"
}
'''.splitlines()

# A stack to hold the parsed objects
stack = [{}]

reader = csv.reader(raw, delimiter=' ', skipinitialspace=True)
for row in reader:
    #print(row)
    key = row[0]
    if key == '}':
        # The end of the current object
        stack.pop()
        continue
    val = row[-1]
    if val == '{':
        # A new subobject
        stack[-1][key] = d = {}
        stack.append(d)
    else:
        # A line of plain data
        stack[-1][key] = val

# Convert to JSON
out = json.dumps(stack[0], indent=4)
print(out)

output

{
    "name": {
        "first_name:": "random"
    },
    "addresses": {
        "location": {
            "locality:": "India",
            "street_address:": "xyz",
            "postal_code:": "300092",
            "full_address:": "street 1 , abc,India"
        }
    },
    "projects": {
        "url:": "www.githib.com"
    }
}
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182