0

So I have a json file which looks something like this

{
"Version": "2.0",
"Description": "A description...",
"A": {
    [...]
},
"B": {
    "B.a": {
        "B.a.a": {
            "Value1": "It's value",
            "Value2": "This value"
        },
        "B.a.1": {
            "Value1": "Value x.a.1",
            "Value2": "Value y.a.1"
        },
        "B.a.2": {
            "Value1": "Value x.a.2",
            "Value2": "Value y.a.2"
        },
        "B.a.3": {
            "Value1": "Value x.a.3",
            "Value2": "Value y.a.3"
        },
        "B.a.4": {
            "Value1": "Value x.a.4",
            "Value2": "Value y.a.4"
        }         
    }
},
"C": {
    [...]
}, ...

Now the rest of my code check if B.a.1 and all others are the values they should have, and if not it will modify it.

with open(file, 'r+') as test:
    data = json.load(test)
    for version in allAVersions:
        data["B"]["B.a"][version['VersionNumber']]['Value1'] = newVersion['Value1'][version['VersionNumer']]['NewValue1']
with open(file, 'w') as test:
    test.write(json.dumps(data, indent=4, sort_keys=True))

This works perfectly fine! But the problem is that it put "B" and all the nodes within it at the start of the file. How can I modify the file so that it stays exactly where it already was. That is, if B.a.1 - Value 1 get a new value then it just changes that value, and the format doesn't change.

Thanks for the help :)

Harbus
  • 311
  • 1
  • 2
  • 8
  • I don't understand the problem. JSON is a data-representation and the order of the elements is irrelevant. Especially since you specify a dictionary (it is interpreted that way by Python) and that is unordered. What do you expect to gain with proper ordering? If it is important you should rethink your data-model. – avanwieringen May 20 '16 at 18:28
  • 1
    Possible duplicate of [Can I get JSON to load into an OrderedDict in Python?](http://stackoverflow.com/questions/6921699/can-i-get-json-to-load-into-an-ordereddict-in-python) – Łukasz Rogalski May 20 '16 at 18:41
  • It's not a duplicate, because im not looking to have it sorted Alphabetically – Harbus May 20 '16 at 18:49

2 Answers2

1

You can use the object_pairs_hook of json.loads|json.load in order to place the items into an OrderedDict. Then instead of setting sort=true keep it as the default. Example:

from collections import OrderedDict
import json
text =""" { "Version": "2.0", "Description": "A description...", "A": { "B.a": { "B.a.a": { "Value1": "It's value", "Value2": "This value" }, "B.a.1": { "Value1": "Value x.a.1", "Value2": "Value y.a.1" }, "B.a.2": { "Value1": "Value x.a.2", "Value2": "Value y.a.2" }, "B.a.3": { "Value1": "Value x.a.3", "Value2": "Value y.a.3" }, "B.a.4": { "Value1": "Value x.a.4", "Value2": "Value y.a.4" } } }, "B": { "B.a": { "B.a.a": { "Value1": "It's value", "Value2": "This value" }, "B.a.1": { "Value1": "Value x.a.1", "Value2": "Value y.a.1" }, "B.a.2": { "Value1": "Value x.a.2", "Value2": "Value y.a.2" }, "B.a.3": { "Value1": "Value x.a.3", "Value2": "Value y.a.3" }, "B.a.4": { "Value1": "Value x.a.4", "Value2": "Value y.a.4" } } }, "C": { "B.a": { "B.a.a": { "Value1": "It's value", "Value2": "This value" }, "B.a.1": { "Value1": "Value x.a.1", "Value2": "Value y.a.1" }, "B.a.2": { "Value1": "Value x.a.2", "Value2": "Value y.a.2" }, "B.a.3": { "Value1": "Value x.a.3", "Value2": "Value y.a.3" }, "B.a.4": { "Value1": "Value x.a.4", "Value2": "Value y.a.4" } } }}"""
json_object = json.loads(text, object_pairs_hook=OrderedDict)
# Change values
json.dumps(json_object, indent=4)
Cory Shay
  • 1,204
  • 8
  • 12
0

You can not.

When you are reading JSON, you are reading it as a dict - the information about original order is lost.

What you may do (however it may even require writing your own JSON writer - I do not know any other solution at the moment) is to write JSON in some canonical form (e.g. with keys ordered lexicographical order). Then given source file is a canonical JSON, you will save it as it was.

abukaj
  • 2,582
  • 1
  • 22
  • 45