-
-
Save allenlinli/b45924bfd933a12f9928 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# encoding: utf-8 | |
def parse_rules(obj): | |
assert obj != None | |
rules = [] | |
stack = [] | |
def _parse(key, item): | |
if isinstance(item, dict): | |
stack.append([key, dict]) | |
for k in item: | |
_parse(k, item[k]) | |
stack.pop() | |
elif isinstance(item, list): | |
stack.append([key, list]) | |
if len(item) == 0: | |
rules.append(stack[:]) | |
stack.pop() | |
return | |
a_child = item[0] | |
_parse("_", a_child) | |
stack.pop() | |
else: | |
types = [basestring, int, bool, float, type(None)] | |
for a_type in types: | |
if isinstance(item, a_type): | |
stack.append([key, a_type]) | |
rules.append(stack[:]) | |
stack.pop() | |
break | |
else: | |
raise Exception("Unknown type found") | |
_parse('/', obj) | |
return rules | |
def format_rule(rule): | |
return "/".join("%s(%s)" % (str(x[0]), str(x[1])) for x in rule) | |
def check_with_rule(rule, obj): | |
assert rule != None | |
assert obj != None | |
assert len(rule) > 0 | |
stack = [] | |
def _check(depth): | |
the_type = stack[-1][0][1] | |
the_obj = stack[-1][1] | |
assert isinstance(the_obj, the_type) | |
if isinstance(the_obj, dict): | |
depth += 1 | |
rule_item = rule[depth] | |
rule_key = rule_item[0] | |
assert rule_key in the_obj | |
stack.append([rule_item, the_obj[rule_key]]) | |
_check(depth) | |
if isinstance(the_obj, list): | |
depth += 1 | |
rule_item = rule[depth] | |
for item in the_obj: | |
stack.append([rule_item, item]) | |
_check(depth) | |
stack.pop() | |
stack.append([rule[0], obj]) | |
_check(0) | |
if __name__ == "__main__": | |
EXAMPLE = ''' | |
{"menu": { | |
"id": "file", | |
"value": "File", | |
"popup": { | |
"menuitem": [ | |
{"value": "New", "onclick": "CreateNewDoc()"}, | |
{"value": "Open", "onclick": "OpenDoc()"}, | |
{"value": "Close", "onclick": "CloseDoc()"} | |
] | |
} | |
}} | |
''' | |
OUTPUT = ''' | |
{"menu": { | |
"id": "1234", | |
"value": "2234", | |
"popup": { | |
"menuitem": [ | |
{"value": "New1212", "onclick": "CreateNewDoc()"}, | |
{"value": "Open1212", "onclick": "OpenDoc()"}, | |
{"value": "Close1212", "onclick": "CloseDoc()"}, | |
{"value": "Close3434", "onclick": "CloseDoc()"} | |
] | |
} | |
}} | |
''' | |
import json | |
example = json.loads(EXAMPLE) | |
rules = parse_rules(example) | |
output = json.loads(OUTPUT) | |
for rule in rules: | |
# print format_rule(rules) | |
check_with_rule(rule, output) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment