跳转到主要内容

json-converter是一个将JSON文档翻译/转换为具有不同结构的另一个JSON文档的工具。

项目描述

安装

pip install json-converter

使用方法

from json_converter.json_mapper import JsonMapper

JSON映射

JsonMapper 类是一个将 JSON 文档转换为具有不同结构的另一个 JSON 文档的工具。映射过程遵循基于字典的规范,该规范描述了字段如何映射到新的 JSON 格式。JsonMapper 的主要功能是 map,它接受一个结构化规范。

    JsonMapper(json_document).map(specification)

映射规范

一般而言,规范描述了转换后的 JSON 文档的结构。基于字典的规范将非常类似于转换后 JSON 的模式。

字段规范

字段规范由一系列参数定义,其中第一个参数是一个名称,它引用了当前 JSON 中要转换的字段。这是唯一必需的字段。

    <converted_field>: [<original_field>]

例如,给定以下示例 JSON 文档,

    {
        "person_name": "Juan dela Cruz"
        "person_age": 37 
    }

可以进行的最简单的映射是将字段名翻译成另一个字段名。例如,要将 person_name 映射到结果 JSON 中的 name,请使用以下规范:

    {
        'name': ['person_name']
    }

字段链

JSON 映射也支持规范两侧的字段链。例如,使用以下规范对上述 JSON 进行映射,

    {
        'person.name': ['person_name'],
        'person.age': ['person_age']
    }

将得到以下转换

    {
        "person": {
            "name": "Juan dela Cruz",
            "age": 37
        }
    }

要将示例中的 JSON 转换回原始 JSON,只需反转字段规范,例如,'person_name': ['person.name']。字段链可以在多个级别上执行。然而,在撰写本文时,JsonMapper 不支持直接对 JSON 数组类型进行字段链。处理此类字段可以通过 锚定嵌套 来表示。

使用通用函数进行后处理

JSON 映射器允许对字段值进行后处理,以执行更复杂的转换规则。这是通过指定一个接受任意数量参数的通用 Python 函数(*args)来完成的。后处理函数在字段规范中位于原始字段名之后指定。

    <converted_field>: [<original_field>, <post_processor>{, <args>}*]

JsonMapper 将将指定字段的值作为第一个参数传递给后处理器。使用上一节中的相同示例,可以使用此功能添加布尔字段 adult。以下规范演示了如何执行此操作:

    {
        'name': ['person_name'],
        'age': ['person_age'],
        'adult': ['person_age', is_adult]
    }

后处理器定义为

    def is_adult(*args):
        age = args[0]
        return age >= 18

在撰写本文时,有一些内置的后处理器可以应用于一些常见的用例,如设置默认值(default_to)、连接列表(concatenate_list)等。这些可以在 post_process.py 模块中找到。

锚定

尽管 JsonMapper 支持字段链,但对于具有多层嵌套的复杂 JSON,以及长的字段名和字段列表,反复提供完整的字段链可能会很繁琐。为了能够更简洁地表达这一点,可以使用锚定。锚定指定将 JSON 结构的根映射到新 JSON 格式,相对于原始 JSON 文档的实际根。

参数 on

JsonMapper 中的 map 函数接受一个名为 on 的参数,可以用来指定开始映射的 JSON 的根。例如,给定以下 JSON,

    {
        "user": {
            "settings": {
                "basic": {...},
                "advanced": {
                    "security": {
                        "javascript_enabled": true,
                        "allow_trackers": false
                    }
                }
            }
        }
    }

处理可以锚定在 user.settings.advanced.security 上以转换安全设置。以下规范,

    {
        'javascript': ['javascript_enabled'],
        'trackers': ['allow_trackers']
    }

应用于上述 JSON,使用 map(specification, on='user.settings.advanced.security'),将得到以下结果:

    {
        "javascript": true,
        "trackers": false
    }

如果没有锚定,则必须在字段规范中始终包含 user.settings.advanced.security,因此 javascript 映射将如下所示:'javascript': ['user.settings.advanced.security.javascript_enabled']

规范 $on

另一种指定锚定字段的方法是直接使用$on关键字将其添加到规范中。与字段规范不同,$on关键字接受一个普通字符串,而不是列表/向量。例如,前面的样本规范可以表示为:

    {
        '$on': 'user.settings.advanced.security',
        "javascript": ['javascript_enabled'],
        "trackers": ['allow_trackers']
    } 

使用此规范,可以不使用on参数调用映射。在撰写本文时,规范中的关键字是区分大小写的,因此$On$ON等不被识别。

链式调用on$on

on参数和$on关键字不会覆盖,而是相互链式连接。在映射调用期间同时存在这两个参数会导致$on字段链与通过on参数提供的值连接。例如,以下调用与上述两个等价

    map({
        '$on': 'advanced.security',
        "javascript": true,
        "trackers": false
    }, on='user.settings')

通过on参数提供的user.settings字段将被视为通过$on关键字指定的advanced.security字段的限定符。

嵌套规范

除了字段规范外,还可以为根规范中的任何识别字段提供嵌套的类似字典的规范。嵌套对于在单个对象上表示嵌套或将对数组中定义的JSON对象列表应用转换很有用。

单对象嵌套

对于单个对象,可以定义嵌套规范以类似于结果JSON对象的外观。以这种方式进行嵌套规范是一种比上述字段链式连接更富有表现力的替代方案。例如,以下类似前几节的JSON,

    {
        "person_name": "Jane Eyre",
        "person_age": 30
    }

可以使用定义了嵌套person对象的嵌套规范进行映射

    {
        'person': {
            'name': ['person_name'],
            'age': ['person_age']
        }
    }

嵌套规范中的锚定也受支持。然而,与主规范中的锚定不同,锚定可以通过on参数表达,嵌套锚定只能使用$on关键字指定。同样重要的是要注意,嵌套锚定相对于父规范定义。例如,以下JSON,

    {
        "product_info" {
            "manufacturing": {
                "location": "Cambridge, UK", 
                "manufacturing_date": "2020-03-05",
                "best_by_date": "2020-09-05"
            }
        }
    }

可以使用以下嵌套规范进行映射,

    {
        '$on': 'product_info',
        'production': {
            '$on': 'manufacturing',
            'date': ['manufacturing_date']
        }
    }

此映射将生成以下JSON

    {
        "production": {
            "date": "2020-03-05"
        }
    }

将规范应用于JSON数组

JSON映射实用程序可以区分JSON对象节点和JSON数组,并相应地应用规范。当它确定规范中引用的字段是JSON对象的集合时,它将迭代地将规则应用于其中每一个。然而,请注意,正如本文档中先前提到的,使用字段链式连接引用嵌套JSON数组目前不支持。要将规范应用于JSON数组,如果它们嵌套在原始JSON文档中,则需要明确锚定

例如,以下JSON对象,

    {
        "books": [
            {
                "title": "A Python Book",
                "price": 23.75
            },
            {
                "title": "A Novel",
                "price": 7.99
            },
            {
                "title": "Compilation of Fun Stuff",
                "price": 10.10
            }
        ]
    }

可以使用以下规范进行翻译(假设定义了translateconvert;有关更多信息,请参阅后处理),

    {
        '$on': 'books',
        'titulo': ['title', translate, 'es'],
        'precio': ['price', convert, 'eur']
    }

请注意,由于规范锚定到books节点,因此只定义了字段规范。以这种方式应用于多个对象的规范表达为如果它应用于单个对象。此示例翻译将返回一个JSON对象数组,而不是包含数组的JSON对象。如果需要嵌套数组,则可以将上述规范嵌套

    {
        'libros': {
            '$on': 'books',
            'titulo': ['title', translate, 'es'],
            'precio': ['price', convert, 'eur']
        }
    }

过滤

在处理数据集合时,有时需要根据某些标准仅处理某些数据。对于JsonMapper,这是通过在规范中使用过滤来完成的。过滤器采用字段规范的形式,第二个参数是一个布尔函数,也称为谓词。

    '$filter': [<original_field>, <predicate_function>{, args}*]

后处理中的通用函数一样,JsonMapper将传递original_field中找到的值作为第一个参数,以及如果存在其余的args

例如,要从上面提供的样本书籍JSON中仅处理价格高于10.00元的书籍,可以使用以下规范

    {
        'expensive_books': {
            '$on': 'books',
            '$filter': ['price', greater_than, 10],
            'book_title': ['title'],
            'book_price': ['price']
        }
    }

使用定义如下谓词 greater_than

    def greater_than(*args):
        number = args[0]
        other_number = args[1]
        return number > other_number

虽然可以对单个JSON节点进行筛选,但应用可能有限。任何被筛选出的JSON对象都将显示为结果文档中的空JSON对象。

JSON文字

在某些情况下,生成的JSON需要包含源JSON文档范围之外的字段和值。在这种情况下,可以定义一个后处理器,该后处理器插入一个预定义的类似字典或列表的结构。然而,JsonMapper 也提供了在规范中包含文字的支持。

使用关键词

如上所述,可以使用两种节点类型将预定义值添加到规范中,分别是对象和数组。要指定JSON对象文字作为结果JSON文档中的字段值,使用 $object 关键词与类似字典的结构

    <field_name>: ['$object', <object_value>]

例如

    'metadata': ['$object', {
        'date_created': '2020-03-13',
        'author': 'Jane Doe'
    }]

对于集合或JSON对象的列表,使用 '$array' 代替

    <field_name>: ['$array': <list>]

例如

    'authors': ['$array', [
        {
            'name': 'Peter Z',
            'institution': 'Some University'
        },
        {
            'name': 'Mary Q',
            'institution': 'Some Research Institute'
        }
    ]]

便利方法

from json_converter.json_mapper import json_object, json_array

为了方便,json_mapper 模块提供了两个辅助方法,允许轻松地将预定义的JSON节点包含到规范中。这些是用于JSON对象的 json_object 和用于JSON数组的 json_arrayjson_object 预期一个类似字典的结构作为输入。

例如,前面的例子可以表示为以下内容

    'metadata': json_object({
        'date_created': '2020-03-13',
        'author': 'Jane Doe'
    })

json_array 方法将参数列表视为JSON对象的列表。例如

    'authors': json_array(
        {
            'name': 'Peter Z',
            'institution': 'Some University'
        },
        {
            'name': 'Mary Q',
            'institution': 'Some Research Institute'
        }
    )

注意,在 json_array 方法中提供的任何列表文字都被视为单个对象。例如,调用 json_array([{'object_id': 123}, {'object_id': 456}]) 结果列表中有一个项目。

更复杂的 $array 和 $object 中的对象

如果将第三个布尔参数 boolean (contains_spec) 设置为 True,则 $array 或 $object 规范中的对象现在可以具有来自源对象的值。

给定以下源对象

source_object = {
                    'name': 'Peter Z',
                    'institution': 'Some University',
                    'address': 'Some place'
                }

使用映射

from json_converter.json_mapper import JsonMapper
from json_converter.post_process import default_to

json_mapper = JsonMapper(source_object)

values = [
            {
                'key': ['', default_to, 'name'],
                'value': ['name']

            },
            {
                'key': ['', default_to, 'institution'],
                'value': ['institution']

            },
            {
                'key': ['', default_to, 'address'],
                'value': ['address']

            },
        ]

result = json_mapper.map({
            'attributes': ['$array', values, True]
        })

# result contains
{
    'attributes':[
        {
            'key': 'name',
            'value': 'Peter Z'
        },
        {
            'key': 'institution',
            'value': 'Some University'
        },
        {
            'key': 'address',
            'value': 'Some place'
        }
    ]
}

项目详情


下载文件

下载适合您平台的文件。如果您不确定要选择哪个,请了解更多关于 安装包 的信息。

源分布

json-converter-0.5.0.tar.gz (13.8 kB 查看散列)

上传时间

构建分布

json_converter-0.5.0-py2.py3-none-any.whl (8.7 kB 查看散列)

上传时间 Python 2 Python 3

支持者