├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── jsonpath └── __init__.py ├── setup.py └── test ├── __init__.py ├── conftest.py ├── data ├── 1.json └── 2.json └── test_jsonpath.py /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | .idea/ 3 | tmp.py 4 | ### Python template 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | cover/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | .pybuilder/ 80 | target/ 81 | 82 | # Jupyter Notebook 83 | .ipynb_checkpoints 84 | 85 | # IPython 86 | profile_default/ 87 | ipython_config.py 88 | 89 | # pyenv 90 | # For a library or package, you might want to ignore these files since the code is 91 | # intended to run in multiple environments; otherwise, check them in: 92 | # .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 102 | __pypackages__/ 103 | 104 | # Celery stuff 105 | celerybeat-schedule 106 | celerybeat.pid 107 | 108 | # SageMath parsed files 109 | *.sage.py 110 | 111 | # Environments 112 | .env 113 | .venv 114 | env/ 115 | venv/ 116 | ENV/ 117 | env.bak/ 118 | venv.bak/ 119 | 120 | # Spyder project settings 121 | .spyderproject 122 | .spyproject 123 | 124 | # Rope project settings 125 | .ropeproject 126 | 127 | # mkdocs documentation 128 | /site 129 | 130 | # mypy 131 | .mypy_cache/ 132 | .dmypy.json 133 | dmypy.json 134 | 135 | # Pyre type checker 136 | .pyre/ 137 | 138 | # pytype static type analyzer 139 | .pytype/ 140 | 141 | # Cython debug symbols 142 | cython_debug/ 143 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [1.0.5](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/compare/v1.0.4...v1.0.5) (2021-03-02) 6 | 7 | 8 | ### Features 9 | 10 | * bump version 1.0.5 ([d5036a4](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/d5036a4cba6d32ecf8b679d48493125e067cb9a4)) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * fix sorter by number string ([8712e4c](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/8712e4c995d0ced09b79b32211155e2567f69564)) 16 | 17 | ### [1.0.4](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/compare/v1.0.3...v1.0.4) (2021-03-02) 18 | 19 | 20 | ### Features 21 | 22 | * bump version 1.0.4 ([5ea02a6](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/5ea02a67bec39ca50ffe141578fdbc5821fa8213)) 23 | 24 | 25 | ### Bug Fixes 26 | 27 | * fix setup.py ([5ba778b](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/5ba778bf877211b9834dd71fc2cb1ae3daa52876)) 28 | 29 | ### [1.0.3](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/compare/v1.0.2...v1.0.3) (2021-03-02) 30 | 31 | 32 | ### Features 33 | 34 | * bump version v1.0.3 ([122fa54](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/122fa54fa0051bafeb8f1e64cd1a9fc1b91b3610)) 35 | * support child operator in field-selector ([f5ec645](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/f5ec645673df67baee248431860ada082fe95006)) 36 | 37 | ### [1.0.2](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/compare/v1.0.1...v1.0.2) (2021-01-13) 38 | 39 | 40 | ### Features 41 | 42 | * bump version v1.0.2 ([36f7bfa](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/36f7bfa51c2bb6ac0991a3f85fac8a4c4e67972e)) 43 | * complete jsonpath syntax ([cca9583](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/cca9583f7910f3abf183f6056103f9dc24d75f0d)), closes [#1](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/issues/1) 44 | * improve regex pattern of select content ([264c2ea](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/264c2ea35cdbdc5806093b27a2b409ca609ecde1)) 45 | 46 | ### 1.0.1 (2021-01-04) 47 | 48 | 49 | ### Features 50 | 51 | * add jsonpath ([c3fc7b0](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/c3fc7b0c4620327d33a2f0bcfe7b2befcbdbd9ff)) 52 | * add output mode: PATH ([3e2bcda](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/3e2bcda7fbbd7636786bd28549253a40bb0d5a28)) 53 | * bump version 0.0.3 ([14da85e](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/14da85e1bda03dd403fd32c71e53dbafac16ec5d)) 54 | * bump version 1.0.0 ([292daff](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/292daff3bfcbde3715d460dcdb9fe6f53921a4b8)) 55 | * bump version 1.0.1 ([f7ad9e1](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/f7ad9e13d1e37f66285bb26bbf2696553a735b03)) 56 | * support operator: field-extractor ([4645c33](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/4645c33a54dda9705c3422c4f18bbfc7d0c9c986)) 57 | * support sorting dict ([4922c94](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/4922c949bf5d74d878b131e2ed70b7d476b3cce0)) 58 | 59 | 60 | ### Bug Fixes 61 | 62 | * fix path mode & add unit tests ([18059d7](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/18059d70e5f808b94b6d381531907b9a8039a111)) 63 | * fix unnecessary-comprehension ([77ad2db](https://gitlab.sz.sensetime.com/its-engineering/toolkit/jsonpath-python/commit/77ad2dbcabd11ac66708b5b9aea226700170fe7f)) 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 zhangxianbing 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # project metadata 2 | NAME := `python setup.py --name` 3 | FULLNAME := `python setup.py --fullname` 4 | VERSION := `python setup.py --version` 5 | BUILD := `git rev-parse --short HEAD` 6 | 7 | .PHONY: info help clean dist docs 8 | .DEFAULT_GOAL := help 9 | 10 | define PRINT_HELP_PYSCRIPT 11 | import re, sys 12 | 13 | for line in sys.stdin: 14 | match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) 15 | if match: 16 | target, help = match.groups() 17 | print("%-20s %s" % (target, help)) 18 | endef 19 | export PRINT_HELP_PYSCRIPT 20 | 21 | info: ## project info 22 | @echo $(FULLNAME) at $(BUILD) 23 | 24 | help: 25 | @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) 26 | 27 | clean: clean-build clean-pyc ## remove all build, test, coverage and Python artifacts 28 | 29 | clean-build: ## remove build artifacts 30 | rm -fr build/ 31 | rm -fr dist/ 32 | rm -fr .eggs/ 33 | find . -name '*.egg-info' -exec rm -fr {} + 34 | find . -name '*.egg' -exec rm -f {} + 35 | 36 | clean-pyc: ## remove Python file artifacts 37 | find . -name '*.pyc' -exec rm -f {} + 38 | find . -name '*.pyo' -exec rm -f {} + 39 | find . -name '*~' -exec rm -f {} + 40 | find . -name '__pycache__' -exec rm -fr {} + 41 | 42 | lint: ## check style with black 43 | find $(NAME) -name '*.py' -type f -not -path "*/pb/*" -not -path "*/data/*" -exec black {} + 44 | 45 | docs: ## format docs 46 | doctoc --gitlab README.md 47 | 48 | install: ## install the package to the active Python's site-packages 49 | pip install . -U --no-index 50 | 51 | uninstall: ## uninstall the package 52 | pip uninstall $(NAME) 53 | 54 | dist: clean ## package 55 | python3 setup.py sdist bdist_wheel 56 | 57 | upload: dist # upload the package to pypi 58 | twine upload dist/* 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | - [jsonpath-python](#jsonpath-python) 2 | - [Features](#features) 3 | - [JSONPath Syntax](#jsonpath-syntax) 4 | - [Operators](#operators) 5 | - [Examples](#examples) 6 | - [Select Fields](#select-fields) 7 | - [Recursive Descent](#recursive-descent) 8 | - [Slice](#slice) 9 | - [Filter Expression](#filter-expression) 10 | - [Sorter Expression](#sorter-expression) 11 | - [Field-Extractor Expression](#field-extractor-expression) 12 | - [Appendix: Example JSON data:](#appendix-example-json-data) 13 | - [Todo List](#todo-list) 14 | 15 | # jsonpath-python 16 | 17 | A more powerful JSONPath implementation in modern python. 18 | 19 | ## Features 20 | 21 | - [x] **Light. (No need to install third-party dependencies.)** 22 | - [x] **Support filter operator, including multi-selection, inverse-selection filtering.** 23 | - [x] **Support sorter operator, including sorting by multiple fields, ascending and descending order.** 24 | - [x] Support basic semantics of JSONPath. 25 | - [x] Support output modes: VALUE, PATH. 26 | - [ ] Support embedded syntax. 27 | - [ ] Support user-defined function. 28 | - [ ] Support parent operator. 29 | 30 | ## Installation 31 | 32 | ```bash 33 | pip install jsonpath-python 34 | 35 | # import 36 | >>> from jsonpath import JSONPath 37 | ``` 38 | 39 | ## JSONPath Syntax 40 | 41 | The JSONPath syntax in this project borrows from [JSONPath - XPath for JSON](http://goessner.net/articles/JSONPath/) and is **modified** and **extended** on it. 42 | 43 | ### Operators 44 | 45 | | Operator | Description | 46 | | ---------------- | ---------------------------------------------------------------------------- | 47 | | `$` | the root object/element | 48 | | `@` | the current object/element | 49 | | `.` or `[]` | child operator | 50 | | `..` | recursive descent | 51 | | `*` | wildcard | 52 | | `''` | (Experimental) wrap field with special character: dots(`.`) and space (` `). | 53 | | `start:end:step` | array slice operator (It's same as the slice in python) | 54 | | `?()` | applies a filter expression | 55 | | `/()` | applies a sorter expression | 56 | | `()` | applies a field-extractor expression | 57 | 58 | ### Examples 59 | 60 | Before running the following example, please import this module and the example data: 61 | 62 | ```python 63 | >>> from jsonpath import JSONPath 64 | 65 | # For the data used in the following example, please refer to the Appendix part. 66 | ``` 67 | 68 | #### Select Fields 69 | 70 | Select a field: 71 | 72 | ```python 73 | >>> JSONPath("$.book").parse(data) 74 | [[{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}]] 75 | >>> JSONPath("$[book]").parse(data) 76 | [[{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}]] 77 | ``` 78 | 79 | (**Experimental**) Select a field with special character: dots(`.`) and space (` `). 80 | 81 | ```python 82 | >>> JSONPath("$.'a.b c'").parse(data) 83 | ['a.b c'] 84 | >>> JSONPath("$['a.b c']").parse(data) 85 | ['a.b c'] 86 | ``` 87 | 88 | Select multiple fields: 89 | 90 | ```python 91 | >>> JSONPath("$[bicycle,scores]").parse(data) 92 | [{'color': 'red', 'price': 19.95}, {'math': {'score': 100, 'avg': 60}, 'english': {'score': 95, 'avg': 80}, 'physic': {'score': 90, 'avg': 70}, 'chemistry': {'score': 85, 'avg': 80}, 'chinese': {'score': 60, 'avg': 75}}] 93 | ``` 94 | 95 | Select all fields using wildcard `*`: 96 | 97 | ```python 98 | >>> JSONPath("$.*").parse(data) 99 | ['a.b c', [{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}], {'color': 'red', 'price': 19.95}, {'math': {'score': 100, 'avg': 60}, 'english': {'score': 95, 'avg': 80}, 'physic': {'score': 90, 'avg': 70}, 'chemistry': {'score': 85, 'avg': 80}, 'chinese': {'score': 60, 'avg': 75}}] 100 | ``` 101 | 102 | #### Recursive Descent 103 | 104 | ```python 105 | >>> JSONPath("$..price").parse(data) 106 | [8.95, 12.99, 8.99, 22.99, 19.95] 107 | ``` 108 | 109 | #### Slice 110 | 111 | Support python-like slice. 112 | 113 | ```python 114 | >>> JSONPath("$.book[1:3]").parse(data) 115 | [{'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}] 116 | >>> JSONPath("$.book[1:-1]").parse(data) 117 | [{'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}] 118 | >>> JSONPath("$.book[0:-1:2]").parse(data) 119 | [{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}] 120 | >>> JSONPath("$.book[-1:1]").parse(data) 121 | [] 122 | >>> JSONPath("$.book[-1:-11:3]").parse(data) 123 | [] 124 | >>> JSONPath("$.book[:]").parse(data) 125 | [{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}] 126 | >>> JSONPath("$.book[::-1]").parse(data) 127 | [{'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99, 'brand': {'version': 'v1.0.3'}}, {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99, 'brand': {'version': 'v1.0.2'}}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99, 'brand': {'version': 'v0.0.1'}}, {'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95, 'brand': {'version': 'v1.0.0'}}] 128 | 129 | ``` 130 | 131 | #### Filter Expression 132 | 133 | Support all python comparison operators (`==`, `!=`, `<`, `>`, `>=`, `<=`), python membership operators (`in`, `not in`), python logical operators (`and`, `or`, `not`). 134 | 135 | ```python 136 | >>> JSONPath("$.book[?(@.price>8 and @.price<9)].price").parse(data) 137 | [8.95, 8.99] 138 | >>> JSONPath('$.book[?(@.category=="reference")].category').parse(data) 139 | ['reference'] 140 | >>> JSONPath('$.book[?(@.category!="reference" and @.price<9)].title').parse(data) 141 | ['Moby Dick'] 142 | >>> JSONPath('$.book[?(@.author=="Herman Melville" or @.author=="Evelyn Waugh")].author').parse(data) 143 | ['Evelyn Waugh', 'Herman Melville'] 144 | ``` 145 | 146 | `Note`: You must use double quote(`""`) instead of single quote(`''`) to wrap the compared string, because single quote(`''`) has another usage in this JSONPath syntax . 147 | 148 | #### Sorter Expression 149 | 150 | Support sorting by multiple fields (using operator `,`) and reverse sort (using operator `~`). 151 | 152 | ```python 153 | >>> JSONPath("$.book[/(price)].price").parse(data) 154 | [8.95, 8.99, 12.99, 22.99] 155 | >>> JSONPath("$.book[/(~price)].price").parse(data) 156 | [22.99, 12.99, 8.99, 8.95] 157 | >>> JSONPath("$.book[/(category,price)].price").parse(data) 158 | [8.99, 12.99, 22.99, 8.95] 159 | >>> JSONPath("$.book[/(brand.version)].brand.version").parse(data) 160 | ['v0.0.1', 'v1.0.0', 'v1.0.2', 'v1.0.3'] 161 | >>> JSONPath("$.scores[/(score)].score").parse(data) 162 | [60, 85, 90, 95, 100] 163 | ``` 164 | 165 | #### Field-Extractor Expression 166 | 167 | Using `(field1,field2,…,filedn)` after a dict object to extract its fields. 168 | 169 | ```python 170 | >>> JSONPath("$.scores[/(score)].(score)").parse(data) 171 | [{'score': 60}, {'score': 85}, {'score': 90}, {'score': 95}, {'score': 100}] 172 | >>> JSONPath("$.book[/(category,price)].(title,price)").parse(data) 173 | [{'title': 'Moby Dick', 'price': 8.99}, {'title': 'Sword of Honour', 'price': 12.99}, {'title': 'The Lord of the Rings', 'price': 22.99}, {'title': 'Sayings of the Century', 'price': 8.95}] 174 | ``` 175 | 176 | ### Appendix: Example JSON data: 177 | 178 | ```python 179 | data = { 180 | "a.b c": "a.b c", 181 | "book": [ 182 | { 183 | "category": "reference", 184 | "author": "Nigel Rees", 185 | "title": "Sayings of the Century", 186 | "price": 8.95, 187 | "brand": { 188 | "version": "v1.0.0" 189 | } 190 | }, 191 | { 192 | "category": "fiction", 193 | "author": "Evelyn Waugh", 194 | "title": "Sword of Honour", 195 | "price": 12.99, 196 | "brand": { 197 | "version": "v0.0.1" 198 | } 199 | }, 200 | { 201 | "category": "fiction", 202 | "author": "Herman Melville", 203 | "title": "Moby Dick", 204 | "isbn": "0-553-21311-3", 205 | "price": 8.99, 206 | "brand": { 207 | "version": "v1.0.2" 208 | } 209 | }, 210 | { 211 | "category": "fiction", 212 | "author": "J. R. R. Tolkien", 213 | "title": "The Lord of the Rings", 214 | "isbn": "0-395-19395-8", 215 | "price": 22.99, 216 | "brand": { 217 | "version": "v1.0.3" 218 | } 219 | } 220 | ], 221 | "bicycle": { 222 | "color": "red", 223 | "price": 19.95 224 | }, 225 | "scores": { 226 | "math": { 227 | "score": 100, 228 | "avg": 60 229 | }, 230 | "english": { 231 | "score": 95, 232 | "avg": 80 233 | }, 234 | "physic": { 235 | "score": 90, 236 | "avg": 70 237 | }, 238 | "chemistry": { 239 | "score": 85, 240 | "avg": 80 241 | }, 242 | "chinese": { 243 | "score": 60, 244 | "avg": 75 245 | } 246 | } 247 | } 248 | ``` 249 | 250 | ## Todo List 251 | 252 | - Syntax and character set (refer to k8s) 253 | 254 | > The name segment is required and must be 63 characters or less, beginning and ending with an alphanumeric character (`[a-z0-9A-Z]`) with dashes (`-`), underscores (`_`), dots (`.`), and alphanumerics between. 255 | -------------------------------------------------------------------------------- /jsonpath/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Author : zhangxianbing 3 | Date : 2020-12-27 09:22:14 4 | LastEditors : zhangxianbing 5 | LastEditTime : 2022-03-14 10:33:55 6 | Description : JSONPath 7 | """ 8 | __version__ = "1.0.6" 9 | __author__ = "zhangxianbing" 10 | 11 | import json 12 | import logging 13 | import os 14 | import re 15 | import sys 16 | from collections import defaultdict 17 | from typing import Union 18 | 19 | 20 | def create_logger(name: str = None, level: Union[int, str] = logging.INFO): 21 | """Get or create a logger used for local debug.""" 22 | 23 | formater = logging.Formatter( 24 | f"%(asctime)s-%(levelname)s-[{name}] %(message)s", datefmt="[%Y-%m-%d %H:%M:%S]" 25 | ) 26 | 27 | handler = logging.StreamHandler() 28 | handler.setLevel(level) 29 | handler.setFormatter(formater) 30 | 31 | logger = logging.getLogger(name) 32 | logger.setLevel(level) 33 | logger.addHandler(handler) 34 | 35 | return logger 36 | 37 | 38 | logger = create_logger("jsonpath", os.getenv("PYLOGLEVEL", "INFO")) 39 | 40 | 41 | class ExprSyntaxError(Exception): 42 | pass 43 | 44 | 45 | class JSONPath: 46 | RESULT_TYPE = { 47 | "VALUE": "A list of specific values.", 48 | "PATH": "All path of specific values.", 49 | } 50 | 51 | # common patterns 52 | SEP = ";" 53 | REP_DOUBLEDOT = re.compile(r"\.\.") 54 | REP_DOT = re.compile(r"(?=|==|!=|>|<| in| not| is)|len\(@\.(.*?)\)" 71 | ) 72 | 73 | # annotations 74 | f: list 75 | segments: list 76 | lpath: int 77 | subx = defaultdict(list) 78 | result: list 79 | result_type: str 80 | eval_func: callable 81 | 82 | def __init__(self, expr: str): 83 | expr = self._parse_expr(expr) 84 | self.segments = expr.split(JSONPath.SEP) 85 | self.lpath = len(self.segments) 86 | logger.debug(f"segments : {self.segments}") 87 | 88 | self.caller_globals = sys._getframe(1).f_globals 89 | 90 | def parse(self, obj, result_type="VALUE", eval_func=eval): 91 | if not isinstance(obj, (list, dict)): 92 | raise TypeError("obj must be a list or a dict.") 93 | 94 | if result_type not in JSONPath.RESULT_TYPE: 95 | raise ValueError( 96 | f"result_type must be one of {tuple(JSONPath.RESULT_TYPE.keys())}" 97 | ) 98 | self.result_type = result_type 99 | self.eval_func = eval_func 100 | 101 | self.result = [] 102 | self._trace(obj, 0, "$") 103 | 104 | return self.result 105 | 106 | def search(self, obj, result_type="VALUE"): 107 | return self.parse(obj, result_type) 108 | 109 | def _parse_expr(self, expr): 110 | logger.debug(f"before expr : {expr}") 111 | # pick up special patterns 112 | expr = JSONPath.REP_GET_QUOTE.sub(self._get_quote, expr) 113 | expr = JSONPath.REP_GET_BACKQUOTE.sub(self._get_backquote, expr) 114 | expr = JSONPath.REP_GET_BRACKET.sub(self._get_bracket, expr) 115 | expr = JSONPath.REP_GET_PAREN.sub(self._get_paren, expr) 116 | # split 117 | expr = JSONPath.REP_DOUBLEDOT.sub(f"{JSONPath.SEP}..{JSONPath.SEP}", expr) 118 | expr = JSONPath.REP_DOT.sub(JSONPath.SEP, expr) 119 | # put back 120 | expr = JSONPath.REP_PUT_PAREN.sub(self._put_paren, expr) 121 | expr = JSONPath.REP_PUT_BRACKET.sub(self._put_bracket, expr) 122 | expr = JSONPath.REP_PUT_BACKQUOTE.sub(self._put_backquote, expr) 123 | expr = JSONPath.REP_PUT_QUOTE.sub(self._put_quote, expr) 124 | if expr.startswith("$;"): 125 | expr = expr[2:] 126 | 127 | logger.debug(f"after expr : {expr}") 128 | return expr 129 | 130 | # TODO abstract get and put procedures 131 | def _get_quote(self, m): 132 | n = len(self.subx["#Q"]) 133 | self.subx["#Q"].append(m.group(1)) 134 | return f"#Q{n}" 135 | 136 | def _put_quote(self, m): 137 | return self.subx["#Q"][int(m.group(1))] 138 | 139 | def _get_backquote(self, m): 140 | n = len(self.subx["#BQ"]) 141 | self.subx["#BQ"].append(m.group(1)) 142 | return f"`#BQ{n}`" 143 | 144 | def _put_backquote(self, m): 145 | return self.subx["#BQ"][int(m.group(1))] 146 | 147 | def _get_bracket(self, m): 148 | n = len(self.subx["#B"]) 149 | self.subx["#B"].append(m.group(1)) 150 | return f".#B{n}" 151 | 152 | def _put_bracket(self, m): 153 | return self.subx["#B"][int(m.group(1))] 154 | 155 | def _get_paren(self, m): 156 | n = len(self.subx["#P"]) 157 | self.subx["#P"].append(m.group(1)) 158 | return f"(#P{n})" 159 | 160 | def _put_paren(self, m): 161 | return self.subx["#P"][int(m.group(1))] 162 | 163 | @staticmethod 164 | def _gen_obj(m): 165 | ret = "__obj" 166 | for e in m.group(1).split("."): 167 | ret += '["%s"]' % e 168 | return ret 169 | 170 | @staticmethod 171 | def _traverse(f, obj, i: int, path: str, *args): 172 | if isinstance(obj, list): 173 | for idx, v in enumerate(obj): 174 | f(v, i, f"{path}{JSONPath.SEP}{idx}", *args) 175 | elif isinstance(obj, dict): 176 | for k, v in obj.items(): 177 | f(v, i, f"{path}{JSONPath.SEP}{k}", *args) 178 | 179 | @staticmethod 180 | def _getattr(obj: dict, path: str, *, convert_number_str=False): 181 | r = obj 182 | for k in path.split("."): 183 | try: 184 | r = r.get(k) 185 | except (AttributeError, KeyError) as err: 186 | logger.error(err) 187 | return None 188 | if convert_number_str and isinstance(r, str): 189 | try: 190 | if r.isdigit(): 191 | return int(r) 192 | return float(r) 193 | except ValueError: 194 | pass 195 | return r 196 | 197 | @staticmethod 198 | def _sorter(obj, sortbys): 199 | for sortby in sortbys.split(",")[::-1]: 200 | if sortby.startswith("~"): 201 | obj.sort( 202 | key=lambda t, k=sortby: JSONPath._getattr( 203 | t[1], k[1:], convert_number_str=True 204 | ), 205 | reverse=True, 206 | ) 207 | else: 208 | obj.sort( 209 | key=lambda t, k=sortby: JSONPath._getattr( 210 | t[1], k, convert_number_str=True 211 | ) 212 | ) 213 | 214 | def _filter(self, obj, i: int, path: str, step: str): 215 | r = False 216 | try: 217 | r = self.eval_func(step, None, {"__obj": obj}) 218 | except Exception as err: 219 | logger.error(err) 220 | if r: 221 | self._trace(obj, i, path) 222 | 223 | def _trace(self, obj, i: int, path): 224 | """Perform operation on object. 225 | 226 | Args: 227 | obj ([type]): current operating object 228 | i (int): current operation specified by index in self.segments 229 | """ 230 | 231 | # store 232 | if i >= self.lpath: 233 | if self.result_type == "VALUE": 234 | self.result.append(obj) 235 | elif self.result_type == "PATH": 236 | self.result.append(path) 237 | logger.debug(f"path: {path} | value: {obj}") 238 | return 239 | 240 | step = self.segments[i] 241 | 242 | # wildcard 243 | if step == "*": 244 | self._traverse(self._trace, obj, i + 1, path) 245 | return 246 | 247 | # recursive descent 248 | if step == "..": 249 | self._trace(obj, i + 1, path) 250 | self._traverse(self._trace, obj, i, path) 251 | return 252 | 253 | # get value from list 254 | if isinstance(obj, list) and step.isdigit(): 255 | ikey = int(step) 256 | if ikey < len(obj): 257 | self._trace(obj[ikey], i + 1, f"{path}{JSONPath.SEP}{step}") 258 | return 259 | 260 | # get value from dict 261 | if isinstance(obj, dict) and step in obj: 262 | self._trace(obj[step], i + 1, f"{path}{JSONPath.SEP}{step}") 263 | return 264 | 265 | # slice 266 | if isinstance(obj, list) and JSONPath.REP_SLICE_CONTENT.fullmatch(step): 267 | obj = list(enumerate(obj)) 268 | vals = self.eval_func(f"obj[{step}]") 269 | for idx, v in vals: 270 | self._trace(v, i + 1, f"{path}{JSONPath.SEP}{idx}") 271 | return 272 | 273 | # select 274 | if isinstance(obj, dict) and JSONPath.REP_SELECT_CONTENT.fullmatch(step): 275 | for k in step.split(","): 276 | if k in obj: 277 | self._trace(obj[k], i + 1, f"{path}{JSONPath.SEP}{k}") 278 | return 279 | 280 | # filter 281 | if step.startswith("?(") and step.endswith(")"): 282 | step = step[2:-1] 283 | step = JSONPath.REP_FILTER_CONTENT.sub(self._gen_obj, step) 284 | self._traverse(self._filter, obj, i + 1, path, step) 285 | return 286 | 287 | # sorter 288 | if step.startswith("/(") and step.endswith(")"): 289 | if isinstance(obj, list): 290 | obj = list(enumerate(obj)) 291 | self._sorter(obj, step[2:-1]) 292 | for idx, v in obj: 293 | self._trace(v, i + 1, f"{path}{JSONPath.SEP}{idx}") 294 | elif isinstance(obj, dict): 295 | obj = list(obj.items()) 296 | self._sorter(obj, step[2:-1]) 297 | for k, v in obj: 298 | self._trace(v, i + 1, f"{path}{JSONPath.SEP}{k}") 299 | else: 300 | raise ExprSyntaxError("sorter must acting on list or dict") 301 | return 302 | 303 | # field-extractor 304 | if step.startswith("(") and step.endswith(")"): 305 | if isinstance(obj, dict): 306 | obj_ = {} 307 | for k in step[1:-1].split(","): 308 | obj_[k] = self._getattr(obj, k) 309 | self._trace(obj_, i + 1, path) 310 | else: 311 | raise ExprSyntaxError("field-extractor must acting on dict") 312 | 313 | return 314 | 315 | 316 | def compile(expr): 317 | return JSONPath(expr) 318 | 319 | 320 | # global cache 321 | _jsonpath_cache = {} 322 | 323 | 324 | def search(expr, data): 325 | global _jsonpath_cache 326 | if expr not in _jsonpath_cache: 327 | _jsonpath_cache[expr] = JSONPath(expr) 328 | return _jsonpath_cache[expr].parse(data) 329 | 330 | 331 | if __name__ == "__main__": 332 | with open("test/data/2.json", "rb") as f: 333 | d = json.load(f) 334 | D = JSONPath("$.scores[/(score)].(score)").parse(d, "VALUE") 335 | print(D) 336 | for v in D: 337 | print(v) 338 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | from jsonpath import __version__, __author__ 3 | 4 | with open("README.md", "r", encoding="utf-8") as fh: 5 | long_description = fh.read() 6 | 7 | setup( 8 | name="jsonpath-python", 9 | version=__version__, 10 | author=__author__, 11 | description="A more powerful JSONPath implementation in modern python", 12 | long_description=long_description, 13 | long_description_content_type="text/markdown", 14 | url="https://github.com/zhangxianbing/jsonpath-python", 15 | packages=find_packages(include=["jsonpath*"]), 16 | classifiers=[ 17 | "Development Status :: 3 - Alpha", 18 | "Intended Audience :: Developers", 19 | "License :: OSI Approved :: MIT License", 20 | "Programming Language :: Python :: 3.6", 21 | ], 22 | python_requires=">=3.6", 23 | ) 24 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sean2077/jsonpath-python/aead1e4db9890f12fc029ca57b9732aa16c62915/test/__init__.py -------------------------------------------------------------------------------- /test/conftest.py: -------------------------------------------------------------------------------- 1 | import json 2 | from collections import namedtuple 3 | 4 | import pytest 5 | 6 | TestCase = namedtuple("TestCase", ("expr", "data", "result")) 7 | 8 | with open("test/data/2.json", "rb") as f: 9 | data = json.load(f) 10 | 11 | 12 | @pytest.fixture( 13 | params=[ 14 | TestCase("$.*", data, list(data.values())), 15 | TestCase("$.book", data, [data["book"]]), 16 | TestCase("$[book]", data, [data["book"]]), 17 | TestCase("$.'a.b c'", data, [data["a.b c"]]), 18 | TestCase("$['a.b c']", data, [data["a.b c"]]), 19 | # recursive descent 20 | TestCase("$..price", data, [8.95, 12.99, 8.99, 22.99, 19.95]), 21 | # slice 22 | TestCase("$.book[1:3]", data, data["book"][1:3]), 23 | TestCase("$.book[1:-1]", data, data["book"][1:-1]), 24 | TestCase("$.book[0:-1:2]", data, data["book"][0:-1:2]), 25 | TestCase("$.book[-1:1]", data, data["book"][-1:1]), 26 | TestCase("$.book[-1:-11:3]", data, data["book"][-1:-11:3]), 27 | TestCase("$.book[:]", data, data["book"][:]), 28 | # filter 29 | TestCase("$.book[?(@.price>8 and @.price<9)].price", data, [8.95, 8.99]), 30 | TestCase('$.book[?(@.category=="reference")].category', data, ["reference"]), 31 | TestCase( 32 | '$.book[?(@.category!="reference" and @.price<9)].title', 33 | data, 34 | ["Moby Dick"], 35 | ), 36 | TestCase( 37 | '$.book[?(@.author=="Herman Melville" or @.author=="Evelyn Waugh")].author', 38 | data, 39 | ["Evelyn Waugh", "Herman Melville"], 40 | ), 41 | # sort 42 | TestCase("$.book[/(price)].price", data, [8.95, 8.99, 12.99, 22.99]), 43 | TestCase("$.book[/(~price)].price", data, [22.99, 12.99, 8.99, 8.95]), 44 | TestCase("$.book[/(category,price)].price", data, [8.99, 12.99, 22.99, 8.95]), 45 | TestCase( 46 | "$.book[/(brand.version)].brand.version", 47 | data, 48 | ["v0.0.1", "v1.0.0", "v1.0.2", "v1.0.3"], 49 | ), 50 | TestCase("$.scores[/(score)].score", data, [60, 85, 90, 95, 100]), 51 | TestCase( 52 | "$.scores[/(score)].(score)", 53 | data, 54 | [ 55 | {"score": 60}, 56 | {"score": 85}, 57 | {"score": 90}, 58 | {"score": 95}, 59 | {"score": 100}, 60 | ], 61 | ), 62 | TestCase( 63 | "$.book[*].(title)", 64 | data, 65 | [ 66 | {"title": "Sayings of the Century"}, 67 | {"title": "Sword of Honour"}, 68 | {"title": "Moby Dick"}, 69 | {"title": "The Lord of the Rings"}, 70 | ], 71 | ), 72 | TestCase( 73 | "$.book[/(category,price)].(title,price)", 74 | data, 75 | [ 76 | {"title": "Moby Dick", "price": 8.99}, 77 | {"title": "Sword of Honour", "price": 12.99}, 78 | {"title": "The Lord of the Rings", "price": 22.99}, 79 | {"title": "Sayings of the Century", "price": 8.95}, 80 | ], 81 | ), 82 | TestCase( 83 | "$.book[*].(title,brand.version)", 84 | data, 85 | [ 86 | {"title": "Sayings of the Century", "brand.version": "v1.0.0"}, 87 | {"title": "Sword of Honour", "brand.version": "v0.0.1"}, 88 | {"title": "Moby Dick", "brand.version": "v1.0.2"}, 89 | {"title": "The Lord of the Rings", "brand.version": "v1.0.3"}, 90 | ], 91 | ), 92 | ] 93 | ) 94 | def value_cases(request): 95 | return request.param 96 | 97 | 98 | @pytest.fixture( 99 | params=[ 100 | TestCase("$.*", data, ["$;a.b c", "$;book", "$;bicycle", "$;scores"]), 101 | TestCase("$.book", data, ["$;book"]), 102 | TestCase("$[book]", data, ["$;book"]), 103 | TestCase("$.'a.b c'", data, ["$;a.b c"]), 104 | TestCase("$['a.b c']", data, ["$;a.b c"]), 105 | # recursive descent 106 | TestCase( 107 | "$..price", 108 | data, 109 | [ 110 | "$;book;0;price", 111 | "$;book;1;price", 112 | "$;book;2;price", 113 | "$;book;3;price", 114 | "$;bicycle;price", 115 | ], 116 | ), 117 | # slice 118 | TestCase("$.book[1:3]", data, ["$;book;1", "$;book;2"]), 119 | TestCase("$.book[1:-1]", data, ["$;book;1", "$;book;2"]), 120 | TestCase("$.book[0:-1:2]", data, ["$;book;0", "$;book;2"]), 121 | TestCase("$.book[-1:1]", data, []), 122 | TestCase("$.book[-1:-11:3]", data, []), 123 | TestCase("$.book[:]", data, ["$;book;0", "$;book;1", "$;book;2", "$;book;3"]), 124 | # filter 125 | TestCase( 126 | "$.book[?(@.price>8 and @.price<9)].price", 127 | data, 128 | ["$;book;0;price", "$;book;2;price"], 129 | ), 130 | TestCase( 131 | '$.book[?(@.category=="reference")].category', data, ["$;book;0;category"] 132 | ), 133 | TestCase( 134 | '$.book[?(@.category!="reference" and @.price<9)].title', 135 | data, 136 | ["$;book;2;title"], 137 | ), 138 | TestCase( 139 | '$.book[?(@.author=="Herman Melville" or @.author=="Evelyn Waugh")].author', 140 | data, 141 | ["$;book;1;author", "$;book;2;author"], 142 | ), 143 | # sort 144 | TestCase( 145 | "$.book[/(price)].price", 146 | data, 147 | ["$;book;0;price", "$;book;2;price", "$;book;1;price", "$;book;3;price"], 148 | ), 149 | TestCase( 150 | "$.book[/(~price)].price", 151 | data, 152 | ["$;book;3;price", "$;book;1;price", "$;book;2;price", "$;book;0;price"], 153 | ), 154 | TestCase( 155 | "$.book[/(category,price)].price", 156 | data, 157 | ["$;book;2;price", "$;book;1;price", "$;book;3;price", "$;book;0;price"], 158 | ), 159 | TestCase( 160 | "$.book[/(brand.version)].brand.version", 161 | data, 162 | [ 163 | "$;book;1;brand;version", 164 | "$;book;0;brand;version", 165 | "$;book;2;brand;version", 166 | "$;book;3;brand;version", 167 | ], 168 | ), 169 | TestCase( 170 | "$.scores[/(score)].score", 171 | data, 172 | [ 173 | "$;scores;chinese;score", 174 | "$;scores;chemistry;score", 175 | "$;scores;physic;score", 176 | "$;scores;english;score", 177 | "$;scores;math;score", 178 | ], 179 | ), 180 | ] 181 | ) 182 | def path_cases(request): 183 | return request.param 184 | -------------------------------------------------------------------------------- /test/data/1.json: -------------------------------------------------------------------------------- 1 | { 2 | "state": 1, 3 | "message": "success", 4 | "content": { 5 | "data": { 6 | "allCitySearchLabels": { 7 | "A": [ 8 | { 9 | "id": 723, 10 | "name": "安阳", 11 | "parentId": 545, 12 | "code": "171500000", 13 | "isSelected": false 14 | }, 15 | { 16 | "id": 601, 17 | "name": "鞍山", 18 | "parentId": 535, 19 | "code": "081600000", 20 | "isSelected": false 21 | }, 22 | { 23 | "id": 671, 24 | "name": "安庆", 25 | "parentId": 541, 26 | "code": "131800000", 27 | "isSelected": false 28 | }, 29 | { 30 | "id": 825, 31 | "name": "安顺", 32 | "parentId": 553, 33 | "code": "240400000", 34 | "isSelected": false 35 | }, 36 | { 37 | "id": 862, 38 | "name": "安康", 39 | "parentId": 556, 40 | "code": "270400000", 41 | "isSelected": false 42 | }, 43 | { 44 | "id": 897, 45 | "name": "阿克苏", 46 | "parentId": 560, 47 | "code": "311800000", 48 | "isSelected": false 49 | }, 50 | { 51 | "id": 598, 52 | "name": "阿拉善盟", 53 | "parentId": 534, 54 | "code": "070300000", 55 | "isSelected": false 56 | }, 57 | { 58 | "id": 105795, 59 | "name": "澳门", 60 | "parentId": 562, 61 | "code": "330100000", 62 | "isSelected": false 63 | }, 64 | { 65 | "id": 903, 66 | "name": "阿勒泰", 67 | "parentId": 560, 68 | "code": "310400000", 69 | "isSelected": false 70 | }, 71 | { 72 | "id": 819, 73 | "name": "阿坝藏族羌族自治州", 74 | "parentId": 552, 75 | "code": "230700000", 76 | "isSelected": false 77 | } 78 | ], 79 | "B": [ 80 | { 81 | "id": 5, 82 | "name": "北京", 83 | "parentId": 1, 84 | "code": "010100000", 85 | "isSelected": false 86 | }, 87 | { 88 | "id": 570, 89 | "name": "保定", 90 | "parentId": 532, 91 | "code": "051100000", 92 | "isSelected": false 93 | }, 94 | { 95 | "id": 666, 96 | "name": "蚌埠", 97 | "parentId": 541, 98 | "code": "131300000", 99 | "isSelected": false 100 | }, 101 | { 102 | "id": 588, 103 | "name": "包头", 104 | "parentId": 534, 105 | "code": "071300000", 106 | "isSelected": false 107 | }, 108 | { 109 | "id": 717, 110 | "name": "滨州", 111 | "parentId": 544, 112 | "code": "161400000", 113 | "isSelected": false 114 | }, 115 | { 116 | "id": 856, 117 | "name": "宝鸡", 118 | "parentId": 556, 119 | "code": "271000000", 120 | "isSelected": false 121 | }, 122 | { 123 | "id": 678, 124 | "name": "亳州", 125 | "parentId": 541, 126 | "code": "130500000", 127 | "isSelected": false 128 | }, 129 | { 130 | "id": 789, 131 | "name": "北海", 132 | "parentId": 549, 133 | "code": "211000000", 134 | "isSelected": false 135 | }, 136 | { 137 | "id": 828, 138 | "name": "毕节", 139 | "parentId": 553, 140 | "code": "240700000", 141 | "isSelected": false 142 | }, 143 | { 144 | "id": 794, 145 | "name": "百色", 146 | "parentId": 549, 147 | "code": "210500000", 148 | "isSelected": false 149 | }, 150 | { 151 | "id": 817, 152 | "name": "巴中", 153 | "parentId": 552, 154 | "code": "230500000", 155 | "isSelected": false 156 | }, 157 | { 158 | "id": 834, 159 | "name": "保山", 160 | "parentId": 554, 161 | "code": "251400000", 162 | "isSelected": false 163 | }, 164 | { 165 | "id": 597, 166 | "name": "巴彦淖尔", 167 | "parentId": 534, 168 | "code": "070400000", 169 | "isSelected": false 170 | }, 171 | { 172 | "id": 867, 173 | "name": "白银", 174 | "parentId": 557, 175 | "code": "281100000", 176 | "isSelected": false 177 | }, 178 | { 179 | "id": 620, 180 | "name": "白城", 181 | "parentId": 536, 182 | "code": "090400000", 183 | "isSelected": false 184 | }, 185 | { 186 | "id": 603, 187 | "name": "本溪", 188 | "parentId": 535, 189 | "code": "081400000", 190 | "isSelected": false 191 | }, 192 | { 193 | "id": 896, 194 | "name": "巴音郭楞", 195 | "parentId": 560, 196 | "code": "311700000", 197 | "isSelected": false 198 | }, 199 | { 200 | "id": 618, 201 | "name": "白山", 202 | "parentId": 536, 203 | "code": "090600000", 204 | "isSelected": false 205 | } 206 | ], 207 | "C": [ 208 | { 209 | "id": 801, 210 | "name": "成都", 211 | "parentId": 552, 212 | "code": "230100000", 213 | "isSelected": false 214 | }, 215 | { 216 | "id": 749, 217 | "name": "长沙", 218 | "parentId": 547, 219 | "code": "190100000", 220 | "isSelected": false 221 | }, 222 | { 223 | "id": 8, 224 | "name": "重庆", 225 | "parentId": 4, 226 | "code": "040100000", 227 | "isSelected": false 228 | }, 229 | { 230 | "id": 613, 231 | "name": "长春", 232 | "parentId": 536, 233 | "code": "090100000", 234 | "isSelected": false 235 | }, 236 | { 237 | "id": 638, 238 | "name": "常州", 239 | "parentId": 539, 240 | "code": "112000000", 241 | "isSelected": false 242 | }, 243 | { 244 | "id": 573, 245 | "name": "沧州", 246 | "parentId": 532, 247 | "code": "050800000", 248 | "isSelected": false 249 | }, 250 | { 251 | "id": 758, 252 | "name": "郴州", 253 | "parentId": 547, 254 | "code": "190500000", 255 | "isSelected": false 256 | }, 257 | { 258 | "id": 590, 259 | "name": "赤峰", 260 | "parentId": 534, 261 | "code": "071100000", 262 | "isSelected": false 263 | }, 264 | { 265 | "id": 673, 266 | "name": "滁州", 267 | "parentId": 541, 268 | "code": "131100000", 269 | "isSelected": false 270 | }, 271 | { 272 | "id": 755, 273 | "name": "常德", 274 | "parentId": 547, 275 | "code": "190800000", 276 | "isSelected": false 277 | }, 278 | { 279 | "id": 572, 280 | "name": "承德", 281 | "parentId": 532, 282 | "code": "050900000", 283 | "isSelected": false 284 | }, 285 | { 286 | "id": 781, 287 | "name": "潮州", 288 | "parentId": 548, 289 | "code": "200500000", 290 | "isSelected": false 291 | }, 292 | { 293 | "id": 611, 294 | "name": "朝阳", 295 | "parentId": 535, 296 | "code": "080600000", 297 | "isSelected": false 298 | }, 299 | { 300 | "id": 905, 301 | "name": "崇左", 302 | "parentId": 549, 303 | "code": "211400000", 304 | "isSelected": false 305 | }, 306 | { 307 | "id": 679, 308 | "name": "池州", 309 | "parentId": 541, 310 | "code": "130600000", 311 | "isSelected": false 312 | }, 313 | { 314 | "id": 836, 315 | "name": "楚雄", 316 | "parentId": 554, 317 | "code": "251200000", 318 | "isSelected": false 319 | }, 320 | { 321 | "id": 894, 322 | "name": "昌吉", 323 | "parentId": 560, 324 | "code": "311500000", 325 | "isSelected": false 326 | }, 327 | { 328 | "id": 848, 329 | "name": "昌都", 330 | "parentId": 555, 331 | "code": "260200000", 332 | "isSelected": false 333 | } 334 | ], 335 | "D": [ 336 | { 337 | "id": 779, 338 | "name": "东莞", 339 | "parentId": 548, 340 | "code": "200300000", 341 | "isSelected": false 342 | }, 343 | { 344 | "id": 600, 345 | "name": "大连", 346 | "parentId": 535, 347 | "code": "081700000", 348 | "isSelected": false 349 | }, 350 | { 351 | "id": 715, 352 | "name": "德州", 353 | "parentId": 544, 354 | "code": "161600000", 355 | "isSelected": false 356 | }, 357 | { 358 | "id": 805, 359 | "name": "德阳", 360 | "parentId": 552, 361 | "code": "231700000", 362 | "isSelected": false 363 | }, 364 | { 365 | "id": 577, 366 | "name": "大同", 367 | "parentId": 533, 368 | "code": "061200000", 369 | "isSelected": false 370 | }, 371 | { 372 | "id": 706, 373 | "name": "东营", 374 | "parentId": 544, 375 | "code": "162000000", 376 | "isSelected": false 377 | }, 378 | { 379 | "id": 815, 380 | "name": "达州", 381 | "parentId": 552, 382 | "code": "230300000", 383 | "isSelected": false 384 | }, 385 | { 386 | "id": 627, 387 | "name": "大庆", 388 | "parentId": 537, 389 | "code": "101300000", 390 | "isSelected": false 391 | }, 392 | { 393 | "id": 604, 394 | "name": "丹东", 395 | "parentId": 535, 396 | "code": "081300000", 397 | "isSelected": false 398 | }, 399 | { 400 | "id": 841, 401 | "name": "大理", 402 | "parentId": 554, 403 | "code": "250700000", 404 | "isSelected": false 405 | }, 406 | { 407 | "id": 874, 408 | "name": "定西", 409 | "parentId": 557, 410 | "code": "280400000", 411 | "isSelected": false 412 | }, 413 | { 414 | "id": 107620, 415 | "name": "儋州", 416 | "parentId": 550, 417 | "code": "220201000", 418 | "isSelected": false 419 | }, 420 | { 421 | "id": 842, 422 | "name": "德宏", 423 | "parentId": 554, 424 | "code": "250600000", 425 | "isSelected": false 426 | } 427 | ], 428 | "E": [ 429 | { 430 | "id": 592, 431 | "name": "鄂尔多斯", 432 | "parentId": 534, 433 | "code": "070900000", 434 | "isSelected": false 435 | }, 436 | { 437 | "id": 741, 438 | "name": "鄂州", 439 | "parentId": 546, 440 | "code": "181600000", 441 | "isSelected": false 442 | }, 443 | { 444 | "id": 748, 445 | "name": "恩施", 446 | "parentId": 546, 447 | "code": "180300000", 448 | "isSelected": false 449 | } 450 | ], 451 | "F": [ 452 | { 453 | "id": 768, 454 | "name": "佛山", 455 | "parentId": 548, 456 | "code": "202000000", 457 | "isSelected": false 458 | }, 459 | { 460 | "id": 681, 461 | "name": "福州", 462 | "parentId": 542, 463 | "code": "140100000", 464 | "isSelected": false 465 | }, 466 | { 467 | "id": 674, 468 | "name": "阜阳", 469 | "parentId": 541, 470 | "code": "131000000", 471 | "isSelected": false 472 | }, 473 | { 474 | "id": 700, 475 | "name": "抚州", 476 | "parentId": 543, 477 | "code": "150200000", 478 | "isSelected": false 479 | }, 480 | { 481 | "id": 602, 482 | "name": "抚顺", 483 | "parentId": 535, 484 | "code": "081500000", 485 | "isSelected": false 486 | }, 487 | { 488 | "id": 790, 489 | "name": "防城港", 490 | "parentId": 549, 491 | "code": "210900000", 492 | "isSelected": false 493 | }, 494 | { 495 | "id": 607, 496 | "name": "阜新", 497 | "parentId": 535, 498 | "code": "081000000", 499 | "isSelected": false 500 | } 501 | ], 502 | "G": [ 503 | { 504 | "id": 763, 505 | "name": "广州", 506 | "parentId": 548, 507 | "code": "200100000", 508 | "isSelected": false 509 | }, 510 | { 511 | "id": 822, 512 | "name": "贵阳", 513 | "parentId": 553, 514 | "code": "240100000", 515 | "isSelected": false 516 | }, 517 | { 518 | "id": 697, 519 | "name": "赣州", 520 | "parentId": 543, 521 | "code": "150500000", 522 | "isSelected": false 523 | }, 524 | { 525 | "id": 787, 526 | "name": "桂林", 527 | "parentId": 549, 528 | "code": "211200000", 529 | "isSelected": false 530 | }, 531 | { 532 | "id": 807, 533 | "name": "广元", 534 | "parentId": 552, 535 | "code": "231900000", 536 | "isSelected": false 537 | }, 538 | { 539 | "id": 792, 540 | "name": "贵港", 541 | "parentId": 549, 542 | "code": "210700000", 543 | "isSelected": false 544 | }, 545 | { 546 | "id": 814, 547 | "name": "广安", 548 | "parentId": 552, 549 | "code": "230200000", 550 | "isSelected": false 551 | }, 552 | { 553 | "id": 820, 554 | "name": "甘孜藏族自治州", 555 | "parentId": 552, 556 | "code": "230800000", 557 | "isSelected": false 558 | }, 559 | { 560 | "id": 889, 561 | "name": "固原", 562 | "parentId": 559, 563 | "code": "300400000", 564 | "isSelected": false 565 | } 566 | ], 567 | "H": [ 568 | { 569 | "id": 653, 570 | "name": "杭州", 571 | "parentId": 540, 572 | "code": "120100000", 573 | "isSelected": false 574 | }, 575 | { 576 | "id": 664, 577 | "name": "合肥", 578 | "parentId": 541, 579 | "code": "130100000", 580 | "isSelected": false 581 | }, 582 | { 583 | "id": 773, 584 | "name": "惠州", 585 | "parentId": 548, 586 | "code": "202500000", 587 | "isSelected": false 588 | }, 589 | { 590 | "id": 622, 591 | "name": "哈尔滨", 592 | "parentId": 537, 593 | "code": "100100000", 594 | "isSelected": false 595 | }, 596 | { 597 | "id": 799, 598 | "name": "海口", 599 | "parentId": 550, 600 | "code": "220100000", 601 | "isSelected": false 602 | }, 603 | { 604 | "id": 587, 605 | "name": "呼和浩特", 606 | "parentId": 534, 607 | "code": "070100000", 608 | "isSelected": false 609 | }, 610 | { 611 | "id": 568, 612 | "name": "邯郸", 613 | "parentId": 532, 614 | "code": "051300000", 615 | "isSelected": false 616 | }, 617 | { 618 | "id": 643, 619 | "name": "淮安", 620 | "parentId": 539, 621 | "code": "112500000", 622 | "isSelected": false 623 | }, 624 | { 625 | "id": 718, 626 | "name": "菏泽", 627 | "parentId": 544, 628 | "code": "160200000", 629 | "isSelected": false 630 | }, 631 | { 632 | "id": 657, 633 | "name": "湖州", 634 | "parentId": 540, 635 | "code": "122200000", 636 | "isSelected": false 637 | }, 638 | { 639 | "id": 752, 640 | "name": "衡阳", 641 | "parentId": 547, 642 | "code": "191100000", 643 | "isSelected": false 644 | }, 645 | { 646 | "id": 575, 647 | "name": "衡水", 648 | "parentId": 532, 649 | "code": "050600000", 650 | "isSelected": false 651 | }, 652 | { 653 | "id": 776, 654 | "name": "河源", 655 | "parentId": 548, 656 | "code": "201400000", 657 | "isSelected": false 658 | }, 659 | { 660 | "id": 108353, 661 | "name": "海外", 662 | "parentId": 108352, 663 | "code": "350100000", 664 | "isSelected": false 665 | }, 666 | { 667 | "id": 737, 668 | "name": "黄石", 669 | "parentId": 546, 670 | "code": "181200000", 671 | "isSelected": false 672 | }, 673 | { 674 | "id": 745, 675 | "name": "黄冈", 676 | "parentId": 546, 677 | "code": "181100000", 678 | "isSelected": false 679 | }, 680 | { 681 | "id": 724, 682 | "name": "鹤壁", 683 | "parentId": 545, 684 | "code": "171600000", 685 | "isSelected": false 686 | }, 687 | { 688 | "id": 760, 689 | "name": "怀化", 690 | "parentId": 547, 691 | "code": "190300000", 692 | "isSelected": false 693 | }, 694 | { 695 | "id": 860, 696 | "name": "汉中", 697 | "parentId": 556, 698 | "code": "270600000", 699 | "isSelected": false 700 | }, 701 | { 702 | "id": 667, 703 | "name": "淮南", 704 | "parentId": 541, 705 | "code": "131400000", 706 | "isSelected": false 707 | }, 708 | { 709 | "id": 669, 710 | "name": "淮北", 711 | "parentId": 541, 712 | "code": "131600000", 713 | "isSelected": false 714 | }, 715 | { 716 | "id": 612, 717 | "name": "葫芦岛", 718 | "parentId": 535, 719 | "code": "080500000", 720 | "isSelected": false 721 | }, 722 | { 723 | "id": 795, 724 | "name": "贺州", 725 | "parentId": 549, 726 | "code": "210400000", 727 | "isSelected": false 728 | }, 729 | { 730 | "id": 593, 731 | "name": "呼伦贝尔", 732 | "parentId": 534, 733 | "code": "070800000", 734 | "isSelected": false 735 | }, 736 | { 737 | "id": 672, 738 | "name": "黄山", 739 | "parentId": 541, 740 | "code": "131900000", 741 | "isSelected": false 742 | }, 743 | { 744 | "id": 796, 745 | "name": "河池", 746 | "parentId": 549, 747 | "code": "210300000", 748 | "isSelected": false 749 | }, 750 | { 751 | "id": 625, 752 | "name": "鹤岗", 753 | "parentId": 537, 754 | "code": "101500000", 755 | "isSelected": false 756 | }, 757 | { 758 | "id": 879, 759 | "name": "海东", 760 | "parentId": 558, 761 | "code": "290200000", 762 | "isSelected": false 763 | }, 764 | { 765 | "id": 837, 766 | "name": "红河", 767 | "parentId": 554, 768 | "code": "251100000", 769 | "isSelected": false 770 | }, 771 | { 772 | "id": 632, 773 | "name": "黑河", 774 | "parentId": 537, 775 | "code": "100800000", 776 | "isSelected": false 777 | }, 778 | { 779 | "id": 893, 780 | "name": "哈密", 781 | "parentId": 560, 782 | "code": "311400000", 783 | "isSelected": false 784 | } 785 | ], 786 | "J": [ 787 | { 788 | "id": 702, 789 | "name": "济南", 790 | "parentId": 544, 791 | "code": "160100000", 792 | "isSelected": false 793 | }, 794 | { 795 | "id": 659, 796 | "name": "金华", 797 | "parentId": 540, 798 | "code": "122400000", 799 | "isSelected": false 800 | }, 801 | { 802 | "id": 656, 803 | "name": "嘉兴", 804 | "parentId": 540, 805 | "code": "122100000", 806 | "isSelected": false 807 | }, 808 | { 809 | "id": 769, 810 | "name": "江门", 811 | "parentId": 548, 812 | "code": "202100000", 813 | "isSelected": false 814 | }, 815 | { 816 | "id": 709, 817 | "name": "济宁", 818 | "parentId": 544, 819 | "code": "162300000", 820 | "isSelected": false 821 | }, 822 | { 823 | "id": 694, 824 | "name": "九江", 825 | "parentId": 543, 826 | "code": "150800000", 827 | "isSelected": false 828 | }, 829 | { 830 | "id": 782, 831 | "name": "揭阳", 832 | "parentId": 548, 833 | "code": "200600000", 834 | "isSelected": false 835 | }, 836 | { 837 | "id": 582, 838 | "name": "晋中", 839 | "parentId": 533, 840 | "code": "060700000", 841 | "isSelected": false 842 | }, 843 | { 844 | "id": 744, 845 | "name": "荆州", 846 | "parentId": 546, 847 | "code": "181900000", 848 | "isSelected": false 849 | }, 850 | { 851 | "id": 614, 852 | "name": "吉林", 853 | "parentId": 536, 854 | "code": "091000000", 855 | "isSelected": false 856 | }, 857 | { 858 | "id": 726, 859 | "name": "焦作", 860 | "parentId": 545, 861 | "code": "171800000", 862 | "isSelected": false 863 | }, 864 | { 865 | "id": 605, 866 | "name": "锦州", 867 | "parentId": 535, 868 | "code": "081200000", 869 | "isSelected": false 870 | }, 871 | { 872 | "id": 698, 873 | "name": "吉安", 874 | "parentId": 543, 875 | "code": "150400000", 876 | "isSelected": false 877 | }, 878 | { 879 | "id": 580, 880 | "name": "晋城", 881 | "parentId": 533, 882 | "code": "060900000", 883 | "isSelected": false 884 | }, 885 | { 886 | "id": 692, 887 | "name": "景德镇", 888 | "parentId": 543, 889 | "code": "151000000", 890 | "isSelected": false 891 | }, 892 | { 893 | "id": 629, 894 | "name": "佳木斯", 895 | "parentId": 537, 896 | "code": "101100000", 897 | "isSelected": false 898 | }, 899 | { 900 | "id": 742, 901 | "name": "荆门", 902 | "parentId": 546, 903 | "code": "181700000", 904 | "isSelected": false 905 | }, 906 | { 907 | "id": 872, 908 | "name": "酒泉", 909 | "parentId": 557, 910 | "code": "280600000", 911 | "isSelected": false 912 | }, 913 | { 914 | "id": 866, 915 | "name": "金昌", 916 | "parentId": 557, 917 | "code": "281200000", 918 | "isSelected": false 919 | }, 920 | { 921 | "id": 107292, 922 | "name": "济源", 923 | "parentId": 545, 924 | "code": "170711000", 925 | "isSelected": false 926 | }, 927 | { 928 | "id": 624, 929 | "name": "鸡西", 930 | "parentId": 537, 931 | "code": "101600000", 932 | "isSelected": false 933 | }, 934 | { 935 | "id": 865, 936 | "name": "嘉峪关", 937 | "parentId": 557, 938 | "code": "281300000", 939 | "isSelected": false 940 | } 941 | ], 942 | "K": [ 943 | { 944 | "id": 831, 945 | "name": "昆明", 946 | "parentId": 554, 947 | "code": "250100000", 948 | "isSelected": false 949 | }, 950 | { 951 | "id": 720, 952 | "name": "开封", 953 | "parentId": 545, 954 | "code": "171200000", 955 | "isSelected": false 956 | }, 957 | { 958 | "id": 899, 959 | "name": "喀什", 960 | "parentId": 560, 961 | "code": "311100000", 962 | "isSelected": false 963 | }, 964 | { 965 | "id": 891, 966 | "name": "克拉玛依", 967 | "parentId": 560, 968 | "code": "311200000", 969 | "isSelected": false 970 | } 971 | ], 972 | "L": [ 973 | { 974 | "id": 574, 975 | "name": "廊坊", 976 | "parentId": 532, 977 | "code": "050700000", 978 | "isSelected": false 979 | }, 980 | { 981 | "id": 864, 982 | "name": "兰州", 983 | "parentId": 557, 984 | "code": "280100000", 985 | "isSelected": false 986 | }, 987 | { 988 | "id": 714, 989 | "name": "临沂", 990 | "parentId": 544, 991 | "code": "162800000", 992 | "isSelected": false 993 | }, 994 | { 995 | "id": 721, 996 | "name": "洛阳", 997 | "parentId": 545, 998 | "code": "171300000", 999 | "isSelected": false 1000 | }, 1001 | { 1002 | "id": 786, 1003 | "name": "柳州", 1004 | "parentId": 549, 1005 | "code": "211300000", 1006 | "isSelected": false 1007 | }, 1008 | { 1009 | "id": 716, 1010 | "name": "聊城", 1011 | "parentId": 544, 1012 | "code": "161500000", 1013 | "isSelected": false 1014 | }, 1015 | { 1016 | "id": 642, 1017 | "name": "连云港", 1018 | "parentId": 539, 1019 | "code": "112400000", 1020 | "isSelected": false 1021 | }, 1022 | { 1023 | "id": 677, 1024 | "name": "六安", 1025 | "parentId": 541, 1026 | "code": "130400000", 1027 | "isSelected": false 1028 | }, 1029 | { 1030 | "id": 804, 1031 | "name": "泸州", 1032 | "parentId": 552, 1033 | "code": "231600000", 1034 | "isSelected": false 1035 | }, 1036 | { 1037 | "id": 729, 1038 | "name": "漯河", 1039 | "parentId": 545, 1040 | "code": "171000000", 1041 | "isSelected": false 1042 | }, 1043 | { 1044 | "id": 585, 1045 | "name": "临汾", 1046 | "parentId": 533, 1047 | "code": "060400000", 1048 | "isSelected": false 1049 | }, 1050 | { 1051 | "id": 810, 1052 | "name": "乐山", 1053 | "parentId": 552, 1054 | "code": "232200000", 1055 | "isSelected": false 1056 | }, 1057 | { 1058 | "id": 689, 1059 | "name": "龙岩", 1060 | "parentId": 542, 1061 | "code": "140400000", 1062 | "isSelected": false 1063 | }, 1064 | { 1065 | "id": 663, 1066 | "name": "丽水", 1067 | "parentId": 540, 1068 | "code": "122800000", 1069 | "isSelected": false 1070 | }, 1071 | { 1072 | "id": 608, 1073 | "name": "辽阳", 1074 | "parentId": 535, 1075 | "code": "080900000", 1076 | "isSelected": false 1077 | }, 1078 | { 1079 | "id": 823, 1080 | "name": "六盘水", 1081 | "parentId": 553, 1082 | "code": "240200000", 1083 | "isSelected": false 1084 | }, 1085 | { 1086 | "id": 847, 1087 | "name": "拉萨", 1088 | "parentId": 555, 1089 | "code": "260100000", 1090 | "isSelected": false 1091 | }, 1092 | { 1093 | "id": 761, 1094 | "name": "娄底", 1095 | "parentId": 547, 1096 | "code": "190200000", 1097 | "isSelected": false 1098 | }, 1099 | { 1100 | "id": 843, 1101 | "name": "丽江", 1102 | "parentId": 554, 1103 | "code": "250500000", 1104 | "isSelected": false 1105 | }, 1106 | { 1107 | "id": 586, 1108 | "name": "吕梁", 1109 | "parentId": 533, 1110 | "code": "060300000", 1111 | "isSelected": false 1112 | }, 1113 | { 1114 | "id": 821, 1115 | "name": "凉山彝族自治州", 1116 | "parentId": 552, 1117 | "code": "230900000", 1118 | "isSelected": false 1119 | }, 1120 | { 1121 | "id": 616, 1122 | "name": "辽源", 1123 | "parentId": 536, 1124 | "code": "090800000", 1125 | "isSelected": false 1126 | }, 1127 | { 1128 | "id": 713, 1129 | "name": "莱芜", 1130 | "parentId": 544, 1131 | "code": "162700000", 1132 | "isSelected": false 1133 | }, 1134 | { 1135 | "id": 876, 1136 | "name": "临夏", 1137 | "parentId": 557, 1138 | "code": "280200000", 1139 | "isSelected": false 1140 | }, 1141 | { 1142 | "id": 904, 1143 | "name": "来宾", 1144 | "parentId": 549, 1145 | "code": "210200000", 1146 | "isSelected": false 1147 | }, 1148 | { 1149 | "id": 875, 1150 | "name": "陇南", 1151 | "parentId": 557, 1152 | "code": "280300000", 1153 | "isSelected": false 1154 | }, 1155 | { 1156 | "id": 853, 1157 | "name": "林芝", 1158 | "parentId": 555, 1159 | "code": "260700000", 1160 | "isSelected": false 1161 | }, 1162 | { 1163 | "id": 846, 1164 | "name": "临沧", 1165 | "parentId": 554, 1166 | "code": "250200000", 1167 | "isSelected": false 1168 | } 1169 | ], 1170 | "M": [ 1171 | { 1172 | "id": 806, 1173 | "name": "绵阳", 1174 | "parentId": 552, 1175 | "code": "231800000", 1176 | "isSelected": false 1177 | }, 1178 | { 1179 | "id": 774, 1180 | "name": "梅州", 1181 | "parentId": 548, 1182 | "code": "202600000", 1183 | "isSelected": false 1184 | }, 1185 | { 1186 | "id": 668, 1187 | "name": "马鞍山", 1188 | "parentId": 541, 1189 | "code": "131500000", 1190 | "isSelected": false 1191 | }, 1192 | { 1193 | "id": 812, 1194 | "name": "眉山", 1195 | "parentId": 552, 1196 | "code": "231300000", 1197 | "isSelected": false 1198 | }, 1199 | { 1200 | "id": 771, 1201 | "name": "茂名", 1202 | "parentId": 548, 1203 | "code": "202300000", 1204 | "isSelected": false 1205 | }, 1206 | { 1207 | "id": 631, 1208 | "name": "牡丹江", 1209 | "parentId": 537, 1210 | "code": "100900000", 1211 | "isSelected": false 1212 | } 1213 | ], 1214 | "N": [ 1215 | { 1216 | "id": 635, 1217 | "name": "南京", 1218 | "parentId": 539, 1219 | "code": "110100000", 1220 | "isSelected": false 1221 | }, 1222 | { 1223 | "id": 691, 1224 | "name": "南昌", 1225 | "parentId": 543, 1226 | "code": "150100000", 1227 | "isSelected": false 1228 | }, 1229 | { 1230 | "id": 654, 1231 | "name": "宁波", 1232 | "parentId": 540, 1233 | "code": "121900000", 1234 | "isSelected": false 1235 | }, 1236 | { 1237 | "id": 785, 1238 | "name": "南宁", 1239 | "parentId": 549, 1240 | "code": "210100000", 1241 | "isSelected": false 1242 | }, 1243 | { 1244 | "id": 641, 1245 | "name": "南通", 1246 | "parentId": 539, 1247 | "code": "112300000", 1248 | "isSelected": false 1249 | }, 1250 | { 1251 | "id": 731, 1252 | "name": "南阳", 1253 | "parentId": 545, 1254 | "code": "170300000", 1255 | "isSelected": false 1256 | }, 1257 | { 1258 | "id": 811, 1259 | "name": "南充", 1260 | "parentId": 552, 1261 | "code": "232300000", 1262 | "isSelected": false 1263 | }, 1264 | { 1265 | "id": 690, 1266 | "name": "宁德", 1267 | "parentId": 542, 1268 | "code": "140300000", 1269 | "isSelected": false 1270 | }, 1271 | { 1272 | "id": 809, 1273 | "name": "内江", 1274 | "parentId": 552, 1275 | "code": "232100000", 1276 | "isSelected": false 1277 | }, 1278 | { 1279 | "id": 688, 1280 | "name": "南平", 1281 | "parentId": 542, 1282 | "code": "140500000", 1283 | "isSelected": false 1284 | } 1285 | ], 1286 | "P": [ 1287 | { 1288 | "id": 683, 1289 | "name": "莆田", 1290 | "parentId": 542, 1291 | "code": "141000000", 1292 | "isSelected": false 1293 | }, 1294 | { 1295 | "id": 722, 1296 | "name": "平顶山", 1297 | "parentId": 545, 1298 | "code": "171400000", 1299 | "isSelected": false 1300 | }, 1301 | { 1302 | "id": 727, 1303 | "name": "濮阳", 1304 | "parentId": 545, 1305 | "code": "171900000", 1306 | "isSelected": false 1307 | }, 1308 | { 1309 | "id": 609, 1310 | "name": "盘锦", 1311 | "parentId": 535, 1312 | "code": "080800000", 1313 | "isSelected": false 1314 | }, 1315 | { 1316 | "id": 693, 1317 | "name": "萍乡", 1318 | "parentId": 543, 1319 | "code": "150900000", 1320 | "isSelected": false 1321 | }, 1322 | { 1323 | "id": 803, 1324 | "name": "攀枝花", 1325 | "parentId": 552, 1326 | "code": "231500000", 1327 | "isSelected": false 1328 | }, 1329 | { 1330 | "id": 10163, 1331 | "name": "普洱", 1332 | "parentId": 554, 1333 | "code": "251700000", 1334 | "isSelected": false 1335 | }, 1336 | { 1337 | "id": 871, 1338 | "name": "平凉", 1339 | "parentId": 557, 1340 | "code": "280700000", 1341 | "isSelected": false 1342 | } 1343 | ], 1344 | "Q": [ 1345 | { 1346 | "id": 703, 1347 | "name": "青岛", 1348 | "parentId": 544, 1349 | "code": "161700000", 1350 | "isSelected": false 1351 | }, 1352 | { 1353 | "id": 685, 1354 | "name": "泉州", 1355 | "parentId": 542, 1356 | "code": "140800000", 1357 | "isSelected": false 1358 | }, 1359 | { 1360 | "id": 778, 1361 | "name": "清远", 1362 | "parentId": 548, 1363 | "code": "200200000", 1364 | "isSelected": false 1365 | }, 1366 | { 1367 | "id": 567, 1368 | "name": "秦皇岛", 1369 | "parentId": 532, 1370 | "code": "051400000", 1371 | "isSelected": false 1372 | }, 1373 | { 1374 | "id": 832, 1375 | "name": "曲靖", 1376 | "parentId": 554, 1377 | "code": "251600000", 1378 | "isSelected": false 1379 | }, 1380 | { 1381 | "id": 660, 1382 | "name": "衢州", 1383 | "parentId": 540, 1384 | "code": "122500000", 1385 | "isSelected": false 1386 | }, 1387 | { 1388 | "id": 623, 1389 | "name": "齐齐哈尔", 1390 | "parentId": 537, 1391 | "code": "101700000", 1392 | "isSelected": false 1393 | }, 1394 | { 1395 | "id": 791, 1396 | "name": "钦州", 1397 | "parentId": 549, 1398 | "code": "210800000", 1399 | "isSelected": false 1400 | }, 1401 | { 1402 | "id": 873, 1403 | "name": "庆阳", 1404 | "parentId": 557, 1405 | "code": "280500000", 1406 | "isSelected": false 1407 | }, 1408 | { 1409 | "id": 827, 1410 | "name": "黔西南", 1411 | "parentId": 553, 1412 | "code": "240600000", 1413 | "isSelected": false 1414 | }, 1415 | { 1416 | "id": 829, 1417 | "name": "黔东南", 1418 | "parentId": 553, 1419 | "code": "240800000", 1420 | "isSelected": false 1421 | }, 1422 | { 1423 | "id": 830, 1424 | "name": "黔南", 1425 | "parentId": 553, 1426 | "code": "240900000", 1427 | "isSelected": false 1428 | }, 1429 | { 1430 | "id": 630, 1431 | "name": "七台河", 1432 | "parentId": 537, 1433 | "code": "101000000", 1434 | "isSelected": false 1435 | } 1436 | ], 1437 | "R": [ 1438 | { 1439 | "id": 712, 1440 | "name": "日照", 1441 | "parentId": 544, 1442 | "code": "162600000", 1443 | "isSelected": false 1444 | }, 1445 | { 1446 | "id": 850, 1447 | "name": "日喀则", 1448 | "parentId": 555, 1449 | "code": "260400000", 1450 | "isSelected": false 1451 | } 1452 | ], 1453 | "S": [ 1454 | { 1455 | "id": 765, 1456 | "name": "深圳", 1457 | "parentId": 548, 1458 | "code": "201700000", 1459 | "isSelected": false 1460 | }, 1461 | { 1462 | "id": 6, 1463 | "name": "上海", 1464 | "parentId": 2, 1465 | "code": "020100000", 1466 | "isSelected": false 1467 | }, 1468 | { 1469 | "id": 639, 1470 | "name": "苏州", 1471 | "parentId": 539, 1472 | "code": "112100000", 1473 | "isSelected": false 1474 | }, 1475 | { 1476 | "id": 599, 1477 | "name": "沈阳", 1478 | "parentId": 535, 1479 | "code": "080100000", 1480 | "isSelected": false 1481 | }, 1482 | { 1483 | "id": 565, 1484 | "name": "石家庄", 1485 | "parentId": 532, 1486 | "code": "050100000", 1487 | "isSelected": false 1488 | }, 1489 | { 1490 | "id": 658, 1491 | "name": "绍兴", 1492 | "parentId": 540, 1493 | "code": "122300000", 1494 | "isSelected": false 1495 | }, 1496 | { 1497 | "id": 648, 1498 | "name": "宿迁", 1499 | "parentId": 539, 1500 | "code": "113000000", 1501 | "isSelected": false 1502 | }, 1503 | { 1504 | "id": 767, 1505 | "name": "汕头", 1506 | "parentId": 548, 1507 | "code": "201900000", 1508 | "isSelected": false 1509 | }, 1510 | { 1511 | "id": 800, 1512 | "name": "三亚", 1513 | "parentId": 550, 1514 | "code": "221800000", 1515 | "isSelected": false 1516 | }, 1517 | { 1518 | "id": 732, 1519 | "name": "商丘", 1520 | "parentId": 545, 1521 | "code": "170400000", 1522 | "isSelected": false 1523 | }, 1524 | { 1525 | "id": 701, 1526 | "name": "上饶", 1527 | "parentId": 543, 1528 | "code": "151100000", 1529 | "isSelected": false 1530 | }, 1531 | { 1532 | "id": 675, 1533 | "name": "宿州", 1534 | "parentId": 541, 1535 | "code": "130200000", 1536 | "isSelected": false 1537 | }, 1538 | { 1539 | "id": 764, 1540 | "name": "韶关", 1541 | "parentId": 548, 1542 | "code": "201600000", 1543 | "isSelected": false 1544 | }, 1545 | { 1546 | "id": 738, 1547 | "name": "十堰", 1548 | "parentId": 546, 1549 | "code": "181300000", 1550 | "isSelected": false 1551 | }, 1552 | { 1553 | "id": 808, 1554 | "name": "遂宁", 1555 | "parentId": 552, 1556 | "code": "232000000", 1557 | "isSelected": false 1558 | }, 1559 | { 1560 | "id": 753, 1561 | "name": "邵阳", 1562 | "parentId": 547, 1563 | "code": "191000000", 1564 | "isSelected": false 1565 | }, 1566 | { 1567 | "id": 775, 1568 | "name": "汕尾", 1569 | "parentId": 548, 1570 | "code": "201500000", 1571 | "isSelected": false 1572 | }, 1573 | { 1574 | "id": 684, 1575 | "name": "三明", 1576 | "parentId": 542, 1577 | "code": "140900000", 1578 | "isSelected": false 1579 | }, 1580 | { 1581 | "id": 747, 1582 | "name": "随州", 1583 | "parentId": 546, 1584 | "code": "180200000", 1585 | "isSelected": false 1586 | }, 1587 | { 1588 | "id": 633, 1589 | "name": "绥化", 1590 | "parentId": 537, 1591 | "code": "100700000", 1592 | "isSelected": false 1593 | }, 1594 | { 1595 | "id": 619, 1596 | "name": "松原", 1597 | "parentId": 536, 1598 | "code": "090500000", 1599 | "isSelected": false 1600 | }, 1601 | { 1602 | "id": 730, 1603 | "name": "三门峡", 1604 | "parentId": 545, 1605 | "code": "170200000", 1606 | "isSelected": false 1607 | }, 1608 | { 1609 | "id": 615, 1610 | "name": "四平", 1611 | "parentId": 536, 1612 | "code": "090900000", 1613 | "isSelected": false 1614 | }, 1615 | { 1616 | "id": 581, 1617 | "name": "朔州", 1618 | "parentId": 533, 1619 | "code": "060800000", 1620 | "isSelected": false 1621 | }, 1622 | { 1623 | "id": 863, 1624 | "name": "商洛", 1625 | "parentId": 556, 1626 | "code": "270300000", 1627 | "isSelected": false 1628 | }, 1629 | { 1630 | "id": 108393, 1631 | "name": "石河子", 1632 | "parentId": 560, 1633 | "code": "310500000", 1634 | "isSelected": false 1635 | }, 1636 | { 1637 | "id": 907, 1638 | "name": "三沙", 1639 | "parentId": 550, 1640 | "code": "220200000", 1641 | "isSelected": false 1642 | }, 1643 | { 1644 | "id": 887, 1645 | "name": "石嘴山", 1646 | "parentId": 559, 1647 | "code": "300200000", 1648 | "isSelected": false 1649 | }, 1650 | { 1651 | "id": 626, 1652 | "name": "双鸭山", 1653 | "parentId": 537, 1654 | "code": "101400000", 1655 | "isSelected": false 1656 | }, 1657 | { 1658 | "id": 849, 1659 | "name": "山南", 1660 | "parentId": 555, 1661 | "code": "260300000", 1662 | "isSelected": false 1663 | } 1664 | ], 1665 | "T": [ 1666 | { 1667 | "id": 7, 1668 | "name": "天津", 1669 | "parentId": 3, 1670 | "code": "030100000", 1671 | "isSelected": false 1672 | }, 1673 | { 1674 | "id": 576, 1675 | "name": "太原", 1676 | "parentId": 533, 1677 | "code": "060100000", 1678 | "isSelected": false 1679 | }, 1680 | { 1681 | "id": 566, 1682 | "name": "唐山", 1683 | "parentId": 532, 1684 | "code": "051500000", 1685 | "isSelected": false 1686 | }, 1687 | { 1688 | "id": 662, 1689 | "name": "台州", 1690 | "parentId": 540, 1691 | "code": "122700000", 1692 | "isSelected": false 1693 | }, 1694 | { 1695 | "id": 647, 1696 | "name": "泰州", 1697 | "parentId": 539, 1698 | "code": "112900000", 1699 | "isSelected": false 1700 | }, 1701 | { 1702 | "id": 710, 1703 | "name": "泰安", 1704 | "parentId": 544, 1705 | "code": "162400000", 1706 | "isSelected": false 1707 | }, 1708 | { 1709 | "id": 591, 1710 | "name": "通辽", 1711 | "parentId": 534, 1712 | "code": "071000000", 1713 | "isSelected": false 1714 | }, 1715 | { 1716 | "id": 670, 1717 | "name": "铜陵", 1718 | "parentId": 541, 1719 | "code": "131700000", 1720 | "isSelected": false 1721 | }, 1722 | { 1723 | "id": 868, 1724 | "name": "天水", 1725 | "parentId": 557, 1726 | "code": "281000000", 1727 | "isSelected": false 1728 | }, 1729 | { 1730 | "id": 826, 1731 | "name": "铜仁", 1732 | "parentId": 553, 1733 | "code": "240500000", 1734 | "isSelected": false 1735 | }, 1736 | { 1737 | "id": 610, 1738 | "name": "铁岭", 1739 | "parentId": 535, 1740 | "code": "080700000", 1741 | "isSelected": false 1742 | }, 1743 | { 1744 | "id": 855, 1745 | "name": "铜川", 1746 | "parentId": 556, 1747 | "code": "271100000", 1748 | "isSelected": false 1749 | }, 1750 | { 1751 | "id": 108355, 1752 | "name": "台湾", 1753 | "parentId": 563, 1754 | "code": "340100000", 1755 | "isSelected": false 1756 | }, 1757 | { 1758 | "id": 617, 1759 | "name": "通化", 1760 | "parentId": 536, 1761 | "code": "090700000", 1762 | "isSelected": false 1763 | }, 1764 | { 1765 | "id": 902, 1766 | "name": "塔城", 1767 | "parentId": 560, 1768 | "code": "310300000", 1769 | "isSelected": false 1770 | }, 1771 | { 1772 | "id": 107384, 1773 | "name": "天门", 1774 | "parentId": 546, 1775 | "code": "180311000", 1776 | "isSelected": false 1777 | } 1778 | ], 1779 | "W": [ 1780 | { 1781 | "id": 736, 1782 | "name": "武汉", 1783 | "parentId": 546, 1784 | "code": "180100000", 1785 | "isSelected": false 1786 | }, 1787 | { 1788 | "id": 636, 1789 | "name": "无锡", 1790 | "parentId": 539, 1791 | "code": "111800000", 1792 | "isSelected": false 1793 | }, 1794 | { 1795 | "id": 655, 1796 | "name": "温州", 1797 | "parentId": 540, 1798 | "code": "122000000", 1799 | "isSelected": false 1800 | }, 1801 | { 1802 | "id": 708, 1803 | "name": "潍坊", 1804 | "parentId": 544, 1805 | "code": "162200000", 1806 | "isSelected": false 1807 | }, 1808 | { 1809 | "id": 665, 1810 | "name": "芜湖", 1811 | "parentId": 541, 1812 | "code": "131200000", 1813 | "isSelected": false 1814 | }, 1815 | { 1816 | "id": 890, 1817 | "name": "乌鲁木齐", 1818 | "parentId": 560, 1819 | "code": "310100000", 1820 | "isSelected": false 1821 | }, 1822 | { 1823 | "id": 711, 1824 | "name": "威海", 1825 | "parentId": 544, 1826 | "code": "162500000", 1827 | "isSelected": false 1828 | }, 1829 | { 1830 | "id": 858, 1831 | "name": "渭南", 1832 | "parentId": 556, 1833 | "code": "270800000", 1834 | "isSelected": false 1835 | }, 1836 | { 1837 | "id": 788, 1838 | "name": "梧州", 1839 | "parentId": 549, 1840 | "code": "211100000", 1841 | "isSelected": false 1842 | }, 1843 | { 1844 | "id": 596, 1845 | "name": "乌兰察布", 1846 | "parentId": 534, 1847 | "code": "070500000", 1848 | "isSelected": false 1849 | }, 1850 | { 1851 | "id": 869, 1852 | "name": "武威", 1853 | "parentId": 557, 1854 | "code": "280900000", 1855 | "isSelected": false 1856 | }, 1857 | { 1858 | "id": 589, 1859 | "name": "乌海", 1860 | "parentId": 534, 1861 | "code": "071200000", 1862 | "isSelected": false 1863 | }, 1864 | { 1865 | "id": 888, 1866 | "name": "吴忠", 1867 | "parentId": 559, 1868 | "code": "300300000", 1869 | "isSelected": false 1870 | }, 1871 | { 1872 | "id": 838, 1873 | "name": "文山", 1874 | "parentId": 554, 1875 | "code": "251000000", 1876 | "isSelected": false 1877 | } 1878 | ], 1879 | "X": [ 1880 | { 1881 | "id": 854, 1882 | "name": "西安", 1883 | "parentId": 556, 1884 | "code": "270100000", 1885 | "isSelected": false 1886 | }, 1887 | { 1888 | "id": 682, 1889 | "name": "厦门", 1890 | "parentId": 542, 1891 | "code": "141100000", 1892 | "isSelected": false 1893 | }, 1894 | { 1895 | "id": 637, 1896 | "name": "徐州", 1897 | "parentId": 539, 1898 | "code": "111900000", 1899 | "isSelected": false 1900 | }, 1901 | { 1902 | "id": 857, 1903 | "name": "咸阳", 1904 | "parentId": 556, 1905 | "code": "270900000", 1906 | "isSelected": false 1907 | }, 1908 | { 1909 | "id": 725, 1910 | "name": "新乡", 1911 | "parentId": 545, 1912 | "code": "171700000", 1913 | "isSelected": false 1914 | }, 1915 | { 1916 | "id": 740, 1917 | "name": "襄阳", 1918 | "parentId": 546, 1919 | "code": "181500000", 1920 | "isSelected": false 1921 | }, 1922 | { 1923 | "id": 728, 1924 | "name": "许昌", 1925 | "parentId": 545, 1926 | "code": "171100000", 1927 | "isSelected": false 1928 | }, 1929 | { 1930 | "id": 569, 1931 | "name": "邢台", 1932 | "parentId": 532, 1933 | "code": "051200000", 1934 | "isSelected": false 1935 | }, 1936 | { 1937 | "id": 878, 1938 | "name": "西宁", 1939 | "parentId": 558, 1940 | "code": "290100000", 1941 | "isSelected": false 1942 | }, 1943 | { 1944 | "id": 733, 1945 | "name": "信阳", 1946 | "parentId": 545, 1947 | "code": "170500000", 1948 | "isSelected": false 1949 | }, 1950 | { 1951 | "id": 743, 1952 | "name": "孝感", 1953 | "parentId": 546, 1954 | "code": "181800000", 1955 | "isSelected": false 1956 | }, 1957 | { 1958 | "id": 751, 1959 | "name": "湘潭", 1960 | "parentId": 547, 1961 | "code": "191200000", 1962 | "isSelected": false 1963 | }, 1964 | { 1965 | "id": 695, 1966 | "name": "新余", 1967 | "parentId": 543, 1968 | "code": "150700000", 1969 | "isSelected": false 1970 | }, 1971 | { 1972 | "id": 746, 1973 | "name": "咸宁", 1974 | "parentId": 546, 1975 | "code": "181000000", 1976 | "isSelected": false 1977 | }, 1978 | { 1979 | "id": 680, 1980 | "name": "宣城", 1981 | "parentId": 541, 1982 | "code": "130700000", 1983 | "isSelected": false 1984 | }, 1985 | { 1986 | "id": 584, 1987 | "name": "忻州", 1988 | "parentId": 533, 1989 | "code": "060500000", 1990 | "isSelected": false 1991 | }, 1992 | { 1993 | "id": 105794, 1994 | "name": "香港", 1995 | "parentId": 561, 1996 | "code": "320100000", 1997 | "isSelected": false 1998 | }, 1999 | { 2000 | "id": 840, 2001 | "name": "西双版纳", 2002 | "parentId": 554, 2003 | "code": "250800000", 2004 | "isSelected": false 2005 | }, 2006 | { 2007 | "id": 762, 2008 | "name": "湘西土家族苗族自治州", 2009 | "parentId": 547, 2010 | "code": "191400000", 2011 | "isSelected": false 2012 | }, 2013 | { 2014 | "id": 594, 2015 | "name": "兴安盟", 2016 | "parentId": 534, 2017 | "code": "070700000", 2018 | "isSelected": false 2019 | }, 2020 | { 2021 | "id": 595, 2022 | "name": "锡林郭勒盟", 2023 | "parentId": 534, 2024 | "code": "070600000", 2025 | "isSelected": false 2026 | } 2027 | ], 2028 | "Y": [ 2029 | { 2030 | "id": 707, 2031 | "name": "烟台", 2032 | "parentId": 544, 2033 | "code": "162100000", 2034 | "isSelected": false 2035 | }, 2036 | { 2037 | "id": 886, 2038 | "name": "银川", 2039 | "parentId": 559, 2040 | "code": "300100000", 2041 | "isSelected": false 2042 | }, 2043 | { 2044 | "id": 645, 2045 | "name": "扬州", 2046 | "parentId": 539, 2047 | "code": "112700000", 2048 | "isSelected": false 2049 | }, 2050 | { 2051 | "id": 644, 2052 | "name": "盐城", 2053 | "parentId": 539, 2054 | "code": "112600000", 2055 | "isSelected": false 2056 | }, 2057 | { 2058 | "id": 739, 2059 | "name": "宜昌", 2060 | "parentId": 546, 2061 | "code": "181400000", 2062 | "isSelected": false 2063 | }, 2064 | { 2065 | "id": 583, 2066 | "name": "运城", 2067 | "parentId": 533, 2068 | "code": "060600000", 2069 | "isSelected": false 2070 | }, 2071 | { 2072 | "id": 813, 2073 | "name": "宜宾", 2074 | "parentId": 552, 2075 | "code": "231200000", 2076 | "isSelected": false 2077 | }, 2078 | { 2079 | "id": 754, 2080 | "name": "岳阳", 2081 | "parentId": 547, 2082 | "code": "190900000", 2083 | "isSelected": false 2084 | }, 2085 | { 2086 | "id": 777, 2087 | "name": "阳江", 2088 | "parentId": 548, 2089 | "code": "201300000", 2090 | "isSelected": false 2091 | }, 2092 | { 2093 | "id": 699, 2094 | "name": "宜春", 2095 | "parentId": 543, 2096 | "code": "150300000", 2097 | "isSelected": false 2098 | }, 2099 | { 2100 | "id": 606, 2101 | "name": "营口", 2102 | "parentId": 535, 2103 | "code": "081100000", 2104 | "isSelected": false 2105 | }, 2106 | { 2107 | "id": 793, 2108 | "name": "玉林", 2109 | "parentId": 549, 2110 | "code": "210600000", 2111 | "isSelected": false 2112 | }, 2113 | { 2114 | "id": 757, 2115 | "name": "益阳", 2116 | "parentId": 547, 2117 | "code": "190600000", 2118 | "isSelected": false 2119 | }, 2120 | { 2121 | "id": 861, 2122 | "name": "榆林", 2123 | "parentId": 556, 2124 | "code": "270500000", 2125 | "isSelected": false 2126 | }, 2127 | { 2128 | "id": 759, 2129 | "name": "永州", 2130 | "parentId": 547, 2131 | "code": "190400000", 2132 | "isSelected": false 2133 | }, 2134 | { 2135 | "id": 833, 2136 | "name": "玉溪", 2137 | "parentId": 554, 2138 | "code": "251500000", 2139 | "isSelected": false 2140 | }, 2141 | { 2142 | "id": 859, 2143 | "name": "延安", 2144 | "parentId": 556, 2145 | "code": "270700000", 2146 | "isSelected": false 2147 | }, 2148 | { 2149 | "id": 578, 2150 | "name": "阳泉", 2151 | "parentId": 533, 2152 | "code": "061100000", 2153 | "isSelected": false 2154 | }, 2155 | { 2156 | "id": 696, 2157 | "name": "鹰潭", 2158 | "parentId": 543, 2159 | "code": "150600000", 2160 | "isSelected": false 2161 | }, 2162 | { 2163 | "id": 816, 2164 | "name": "雅安", 2165 | "parentId": 552, 2166 | "code": "230400000", 2167 | "isSelected": false 2168 | }, 2169 | { 2170 | "id": 783, 2171 | "name": "云浮", 2172 | "parentId": 548, 2173 | "code": "200700000", 2174 | "isSelected": false 2175 | }, 2176 | { 2177 | "id": 901, 2178 | "name": "伊犁", 2179 | "parentId": 560, 2180 | "code": "310200000", 2181 | "isSelected": false 2182 | }, 2183 | { 2184 | "id": 621, 2185 | "name": "延边", 2186 | "parentId": 536, 2187 | "code": "090300000", 2188 | "isSelected": false 2189 | }, 2190 | { 2191 | "id": 628, 2192 | "name": "伊春", 2193 | "parentId": 537, 2194 | "code": "101200000", 2195 | "isSelected": false 2196 | } 2197 | ], 2198 | "Z": [ 2199 | { 2200 | "id": 719, 2201 | "name": "郑州", 2202 | "parentId": 545, 2203 | "code": "170100000", 2204 | "isSelected": false 2205 | }, 2206 | { 2207 | "id": 766, 2208 | "name": "珠海", 2209 | "parentId": 548, 2210 | "code": "201800000", 2211 | "isSelected": false 2212 | }, 2213 | { 2214 | "id": 780, 2215 | "name": "中山", 2216 | "parentId": 548, 2217 | "code": "200400000", 2218 | "isSelected": false 2219 | }, 2220 | { 2221 | "id": 704, 2222 | "name": "淄博", 2223 | "parentId": 544, 2224 | "code": "161800000", 2225 | "isSelected": false 2226 | }, 2227 | { 2228 | "id": 646, 2229 | "name": "镇江", 2230 | "parentId": 539, 2231 | "code": "112800000", 2232 | "isSelected": false 2233 | }, 2234 | { 2235 | "id": 824, 2236 | "name": "遵义", 2237 | "parentId": 553, 2238 | "code": "240300000", 2239 | "isSelected": false 2240 | }, 2241 | { 2242 | "id": 750, 2243 | "name": "株洲", 2244 | "parentId": 547, 2245 | "code": "191300000", 2246 | "isSelected": false 2247 | }, 2248 | { 2249 | "id": 770, 2250 | "name": "湛江", 2251 | "parentId": 548, 2252 | "code": "202200000", 2253 | "isSelected": false 2254 | }, 2255 | { 2256 | "id": 772, 2257 | "name": "肇庆", 2258 | "parentId": 548, 2259 | "code": "202400000", 2260 | "isSelected": false 2261 | }, 2262 | { 2263 | "id": 687, 2264 | "name": "漳州", 2265 | "parentId": 542, 2266 | "code": "140600000", 2267 | "isSelected": false 2268 | }, 2269 | { 2270 | "id": 734, 2271 | "name": "周口", 2272 | "parentId": 545, 2273 | "code": "170600000", 2274 | "isSelected": false 2275 | }, 2276 | { 2277 | "id": 571, 2278 | "name": "张家口", 2279 | "parentId": 532, 2280 | "code": "051000000", 2281 | "isSelected": false 2282 | }, 2283 | { 2284 | "id": 705, 2285 | "name": "枣庄", 2286 | "parentId": 544, 2287 | "code": "161900000", 2288 | "isSelected": false 2289 | }, 2290 | { 2291 | "id": 579, 2292 | "name": "长治", 2293 | "parentId": 533, 2294 | "code": "061000000", 2295 | "isSelected": false 2296 | }, 2297 | { 2298 | "id": 735, 2299 | "name": "驻马店", 2300 | "parentId": 545, 2301 | "code": "170700000", 2302 | "isSelected": false 2303 | }, 2304 | { 2305 | "id": 835, 2306 | "name": "昭通", 2307 | "parentId": 554, 2308 | "code": "251300000", 2309 | "isSelected": false 2310 | }, 2311 | { 2312 | "id": 818, 2313 | "name": "资阳", 2314 | "parentId": 552, 2315 | "code": "230600000", 2316 | "isSelected": false 2317 | }, 2318 | { 2319 | "id": 802, 2320 | "name": "自贡", 2321 | "parentId": 552, 2322 | "code": "231400000", 2323 | "isSelected": false 2324 | }, 2325 | { 2326 | "id": 661, 2327 | "name": "舟山", 2328 | "parentId": 540, 2329 | "code": "122600000", 2330 | "isSelected": false 2331 | }, 2332 | { 2333 | "id": 756, 2334 | "name": "张家界", 2335 | "parentId": 547, 2336 | "code": "190700000", 2337 | "isSelected": false 2338 | }, 2339 | { 2340 | "id": 906, 2341 | "name": "中卫", 2342 | "parentId": 559, 2343 | "code": "300500000", 2344 | "isSelected": false 2345 | }, 2346 | { 2347 | "id": 870, 2348 | "name": "张掖", 2349 | "parentId": 557, 2350 | "code": "280800000", 2351 | "isSelected": false 2352 | } 2353 | ] 2354 | } 2355 | }, 2356 | "rows": [] 2357 | } 2358 | } -------------------------------------------------------------------------------- /test/data/2.json: -------------------------------------------------------------------------------- 1 | { 2 | "a.b c": "a.b c", 3 | "book": [ 4 | { 5 | "category": "reference", 6 | "author": "Nigel Rees", 7 | "title": "Sayings of the Century", 8 | "price": 8.95, 9 | "brand": { 10 | "version": "v1.0.0" 11 | } 12 | }, 13 | { 14 | "category": "fiction", 15 | "author": "Evelyn Waugh", 16 | "title": "Sword of Honour", 17 | "price": 12.99, 18 | "brand": { 19 | "version": "v0.0.1" 20 | } 21 | }, 22 | { 23 | "category": "fiction", 24 | "author": "Herman Melville", 25 | "title": "Moby Dick", 26 | "isbn": "0-553-21311-3", 27 | "price": 8.99, 28 | "brand": { 29 | "version": "v1.0.2" 30 | } 31 | }, 32 | { 33 | "category": "fiction", 34 | "author": "J. R. R. Tolkien", 35 | "title": "The Lord of the Rings", 36 | "isbn": "0-395-19395-8", 37 | "price": 22.99, 38 | "brand": { 39 | "version": "v1.0.3" 40 | } 41 | } 42 | ], 43 | "bicycle": { 44 | "color": "red", 45 | "price": 19.95 46 | }, 47 | "scores": { 48 | "math": { 49 | "score": 100, 50 | "avg": 60 51 | }, 52 | "english": { 53 | "score": 95, 54 | "avg": 80 55 | }, 56 | "physic": { 57 | "score": 90, 58 | "avg": 70 59 | }, 60 | "chemistry": { 61 | "score": 85, 62 | "avg": 80 63 | }, 64 | "chinese": { 65 | "score": 60, 66 | "avg": 75 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /test/test_jsonpath.py: -------------------------------------------------------------------------------- 1 | from jsonpath import JSONPath 2 | 3 | 4 | def test_value_cases(value_cases): 5 | print(value_cases.expr) 6 | r = JSONPath(value_cases.expr).parse(value_cases.data) 7 | assert r == value_cases.result 8 | 9 | 10 | def test_path_cases(path_cases): 11 | print(path_cases.expr) 12 | r = JSONPath(path_cases.expr).parse(path_cases.data, "PATH") 13 | assert r == path_cases.result 14 | --------------------------------------------------------------------------------