Skip to content

Commit 6caa9d4

Browse files
committed
fix: resolve issue #16 support quoted keys in filters and paths
1 parent 47bba25 commit 6caa9d4

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

jsonpath/jsonpath.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def _get_quote(self, m):
118118
return f"#Q{n}"
119119

120120
def _put_quote(self, m):
121-
return self.subx["#Q"][int(m.group(1))]
121+
return f"'{self.subx['#Q'][int(m.group(1))]}'"
122122

123123
def _get_backquote(self, m):
124124
n = len(self.subx["#BQ"])
@@ -146,8 +146,11 @@ def _put_paren(self, m):
146146

147147
@staticmethod
148148
def _gen_obj(m):
149+
content = m.group(1) or m.group(2) # group 2 is for len()
149150
ret = "__obj"
150-
for e in m.group(1).split("."):
151+
for e in content.split("."):
152+
if len(e) >= 2 and ((e[0] == "'" and e[-1] == "'") or (e[0] == '"' and e[-1] == '"')):
153+
e = e[1:-1]
151154
ret += f'["{e}"]'
152155
return ret
153156

@@ -239,11 +242,15 @@ def _trace(self, obj, i: int, path):
239242
return
240243

241244
# get value from dict
242-
if isinstance(obj, dict) and step in obj:
243-
if re.match(r"^\w+$", step):
244-
self._trace(obj[step], i + 1, f"{path}.{step}")
245+
step_key = step
246+
if len(step) >= 2 and step[0] == "'" and step[-1] == "'":
247+
step_key = step[1:-1]
248+
249+
if isinstance(obj, dict) and step_key in obj:
250+
if re.match(r"^\w+$", step_key):
251+
self._trace(obj[step_key], i + 1, f"{path}.{step_key}")
245252
else:
246-
self._trace(obj[step], i + 1, f"{path}['{step}']")
253+
self._trace(obj[step_key], i + 1, f"{path}['{step_key}']")
247254
return
248255

249256
# slice

tests/test_issues.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,22 @@ def test_issue_17_bracket_dot_normalization():
2525
data_recursive = {"a": {"store": "book"}, "b": {"store": "paper"}}
2626
# $..['store'] should find all 'store' keys
2727
assert sorted(JSONPath("$..['store']").parse(data_recursive)) == ["book", "paper"]
28+
29+
30+
def test_issue_16_quoted_keys():
31+
data = {"user-list": [{"city-name": "Austin", "name": "John"}, {"city-name": "New York", "name": "Jane"}]}
32+
33+
# Case 1: Key with hyphen in the path
34+
assert JSONPath("$.'user-list'").parse(data) == [
35+
[{"city-name": "Austin", "name": "John"}, {"city-name": "New York", "name": "Jane"}]
36+
]
37+
38+
# Case 2: Key with hyphen in a filter (single quotes)
39+
assert JSONPath("$.'user-list'[?(@.'city-name'=='Austin')]").parse(data) == [
40+
{"city-name": "Austin", "name": "John"}
41+
]
42+
43+
# Case 3: Key with hyphen in a filter (double quotes)
44+
assert JSONPath('$.\'user-list\'[?(@."city-name"=="Austin")]').parse(data) == [
45+
{"city-name": "Austin", "name": "John"}
46+
]

0 commit comments

Comments
 (0)