如果使用 JMESPath 选择另一个 JSON 密钥,则选择第一个 JSON 密钥的最佳方法是

例如,有一些包含一些产品数据的 JSON:


{

  "sku": 123,

  "product": {

    "name": "Some name",

    "images": {

      "normalImage": "http://somelink.com/1.jpg",

      "bigImage": "http://somelink.com/1b.jpg"

    }

  }

}

我想选择图像链接,但仅存在于某些产品中,因此有时我需要选择。bigImagenormalImage


显而易见的解决方案是这样的:


jmespath.search('product.images.bigImage') or jmespath.search('product.images.normalImage')

但我觉得可以做得更好。如何使用 JMESPath 语法以最佳方式执行此操作?


一只萌萌小番薯
浏览 66回答 2
2回答

繁花如伊

以下仅使用 JMESPath 语法的情况如何?product.images.[bigImage, normalImage][?@]|[0]我们的想法是,我们按照偏好顺序制作一个要使用的所有图像的数组,过滤掉丢失的图像,然后选择剩余数组中的第一个项目。警告 - 这不会区分缺失值和(或其他“错误”值,例如空字符串),因此,如果这对您的特定情况很重要,则可能需要对其进行一些调整。null

胡说叔叔

您可以创建一个类来执行此操作,类似于 GitHub 页面中给出的示例。CustomFunctionsfrom jmespath import searchfrom jmespath import functionsfrom jmespath import Optionsfrom json import loadsclass CustomFunctions(functions.Functions):    # Method that selects 'bigImage' key value if it exists    # Otherwise return 'normalImage' value    # dict.get() is perfect for this, since it returns a default value if a key doesn't exist    # Use type 'object' since thats the equivalant type to a Python dictionary in JSON    # Make sure to decorate function signature as well to indicate types    # Make sure to also put _func_ before your function name    @functions.signature({'types': ['object']})    def _func_choose_key(self, d):        return d.get('bigImage', d['normalImage'])if __name__ == "__main__":    # Get custom function options    options = Options(custom_functions=CustomFunctions())    # Test method which runs JMESPath query with custom function    def test(json):        json_dict = loads(json)        return search('product.images | choose_key(@)', json_dict, options=options)    # TEST 1 - bigImage key exists    json1 = """{        "sku": 123,        "product": {            "name": "Some name",            "images": {                "normalImage": "http://somelink.com/1.jpg",                "bigImage": "http://somelink.com/1b.jpg"            }        }    }"""    print("Test1: %s" % test(json1))    # TEST 2 - bigImage key doesn't exist    json2 = """{        "sku": 123,        "product": {            "name": "Some name",            "images": {                "normalImage": "http://somelink.com/1.jpg"            }        }    }"""    print("Test2: %s" % test(json2))这将打印出以下结果:Test1: http://somelink.com/1b.jpg  # When bigImage key existsTest2: http://somelink.com/1.jpg   # When bigImage key doesn't exist如果JMESPath变得太复杂,我们总是可以使用旧的标准字典方法:def test2(json):    json_dict = loads(json)    images = json_dict["product"]["images"]    return images.get("bigImage", images["normalImage"])# TEST 1 - bigImage key existsjson1 = """{    "sku": 123,    "product": {        "name": "Some name",        "images": {            "normalImage": "http://somelink.com/1.jpg",            "bigImage": "http://somelink.com/1b.jpg"        }    }}"""print("Test1: %s" % test2(json1))# TEST 2 - bigImage key doesn't existjson2 = """{    "sku": 123,    "product": {        "name": "Some name",        "images": {            "normalImage": "http://somelink.com/1.jpg"        }    }}"""print("Test2: %s" % test2(json2))这也打印相同的结果:Test1: http://somelink.com/1b.jpg  # When bigImage key existsTest2: http://somelink.com/1.jpg   # When bigImage key doesn't exist
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python