在Go语言中向现有的JSON中添加根元素。

huangapple go评论82阅读模式
英文:

Add root element to existing Json in Go lang

问题

我正在尝试将字符串"Employee"添加到现有的JSON响应中。此外,我们需要能够根据用户条件生成此版本的JSON。只有当满足用户条件时,我才需要生成带有字符串"Employee"的第二个版本的JSON。如果不满足条件,则应生成不带字符串"Employee"的第一个版本。如何在不更新现有struct的情况下实现这一点?如何使用if语句检查条件,然后根据条件生成JSON?

以下是我现有的Go语言JSON响应:

[
   {
      "EmpId":{
         "String":"ABCD",
         "Valid":true
      },
      "Department":{
         "Float64":0,
         "Valid":true
      }
   }
]

如何在不更改现有结构的情况下,根据输入参数获取以下JSON响应?

{
   "Employee":[
      {
         "EmpId":{
            "String":"ABCD",
            "Valid":true
         },
         "Department":{
            "Float64":0,
            "Valid":true
         }
      }
   ]
}

以下是我的代码:
第1步:model文件夹

type EmployeeWithRoot struct {
	Employee []Employee
}
type Employee struct {
	EmpNbr     sql.NullString  `json:"EmpNbr"`
	DateofJoin      sql.NullString   `json:"DateofJoin"`
	DeptId  sql.NullString  `json:"DeptId"`
	DeptName sql.NullString  `json:"DeptName"`
}

第2步:code文件夹

func GetEmpDetails(logRequestId string, logNestedLevel int, EmpNbr string, DateofJoin string) ([]model.EmployeeWithRoot, error) {
	logFunctionFunctionName := "code.GetEmpDetails"
	logStartTime := time.Now()
	logNestedLevel++
	defer configurations.TimeTrack(logFunctionFunctionName, logRequestId, logStartTime, logNestedLevel)
	rows, err := db.Query(utils.SELECT_OF_EMP_AGGR, EmpNbr, DateofJoin, DeptId, DeptName)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var e []model.EmployeeWithRoot
	for rows.Next() {
		var x model.EmployeeWithRoot
		err := rows.Scan(&x.Employee.EmpNbr, &x.Employee.DateofJoin, &x.Employee.DeptId,&x.Employee.DeptName)
		if err != nil {
			return nil, err
		}
		e = append(e, x)
	}
	err = rows.Err()
	if err != nil {
		return nil, err
	}
	return e, nil
}

第3步:API文件夹

Employee, err := code.GetEmpDetails(logRequestId, logNestedLevel, EmpNbr, DateofJoin)
if err != nil {
	log.Panic(err)
}
marshalDataForRequestContentType(logRequestId, logNestedLevel, w, r, Employee)

我收到以下错误信息:

x.Employee.EmpNbr未定义(类型[]model.Employee没有字段或方法EmpNbr)
x.Employee.DateofJoin未定义(类型[]model.Employee没有字段或方法DateofJoin)
x.Employee.DeptId未定义(类型[]model.Employee没有字段或方法DeptId)
x.Employee.DeptName未定义(类型[]model.Employee没有字段或方法DeptName)

英文:

I'm trying to add string "Employee" to my existing JSON response. Also, we need to be able to generate this version of json based on an user condition. Only if the user condition is met, I need to generate second version of json with string "Employee" added. If not the first version without string "Employee" should be generated. How can I achieve it with out updating the existing struct and how can I check this with if clause to check for the condition and then generate json based on it?

Below is my existing json response in go

[
   {
      "EmpId":{
         "String":"ABCD",
         "Valid":true
      },
      "Department":{
         "Float64":0,
         "Valid":true
      }
   }
]

How can I get my json response like below with out changing existing struct based on input parameter?

{
   "Employee":[
      {
         "EmpId":{
            "String":"ABCD",
            "Valid":true
         },
         "Department":{
            "Float64":0,
            "Valid":true
         }
      }
   ]
}

Below is my code:
Step 1: model folder

type EmployeeWithRoot struct {
	Employee []Employee
}
type Employee struct {
	EmpNbr     sql.NullString  `json:"EmpNbr"`
	DateofJoin      sql.NullString   `json:"DateofJoin"`
        DeptId  sql.NullString  `json:"DeptId"`
        DeptName sql.NullString  `json:"DeptName"`
}

Step 2: code folder

func GetEmpDetails(logRequestId string, logNestedLevel int, EmpNbr string, DateofJoin string) ([]model.EmployeeWithRoot, error) {
	logFunctionFunctionName := "code.GetEmpDetails"
	logStartTime := time.Now()
	logNestedLevel++
	defer configurations.TimeTrack(logFunctionFunctionName, logRequestId, logStartTime, logNestedLevel)
	rows, err := db.Query(utils.SELECT_OF_EMP_AGGR, EmpNbr, DateofJoin, DeptId, DeptName)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var e []model.EmployeeWithRoot
	for rows.Next() {
		var x model.EmployeeWithRoot
		err := rows.Scan(&x.Employee.EmpNbr, &x.Employee.DateofJoin, &x.Employee.DeptId,&x.Employee.DeptName)
		if err != nil {
			return nil, err
		}
		e = append(e, x)
	}
	err = rows.Err()
	if err != nil {
		return nil, err
	}
	return e, nil
}

STEP 3: API folder

Employee, err := code.GetEmpDetails(logRequestId, logNestedLevel, EmpNbr, DateofJoin)
	if err != nil {
		log.Panic(err)
	}
	marshalDataForRequestContentType(logRequestId, logNestedLevel, w, r, Employee)

I'm getting the below error.

x.Employee.EmpNbr undefined (type []model.Employee has no field or method EmpNbr)
x.Employee.DateofJoin undefined (type []model.Employee has no field or method DateofJoin)enter code here
x.Employee.DeptId undefined (type []model.Employee has no field or method DeptId)
x.Employee.DeptName undefined (type []model.Employee has no field or method DeptName)

答案1

得分: 1

考虑到你只是将它包装在一个外部对象中,我不认为你需要更改现有的结构,只需将其包装在一个新的结构中即可。由于你只展示了 JSON 而没有展示生成它的 Go 代码,所以我需要做一些猜测和假设。假设你现有的 JSON 是通过类似 var response []Employee 这样的编组生成的,那么可以通过以下方式生成所需的 JSON:

json.Marshal(struct{Employee []Employee}{response})

工作示例:https://go.dev/play/p/vwDvxnQ96G_2

英文:

Considering you're just wrapping it it an outer object, I don't see any reason you'd need to change the existing struct, just wrap it in a new one. I'll have to make some guesses/assumptions here since you've only shown the JSON and not the Go code that produces it, but assuming your existing JSON is produced by marshaling something like var response []Employee, the desired JSON could be produced in your condition by marshaling instead:

json.Marshal(struct{Employee []Employee}{response})

Working example: https://go.dev/play/p/vwDvxnQ96G_2

答案2

得分: 0

使用字符串拼接:

func addRoot(json string) string {
    return `{ "Employee":` + json + `}`
}

在 GoLang playground 上运行示例

如果你使用的是 []byte 而不是字符串,可以使用以下代码:

func addRoot(json []byte) []byte {
    const prefix = `{ "Employee":`
    const suffix = `}`
    result := make([]byte, 0, len(prefix)+len(json)+len(suffix))
    return append(append(append(result, prefix...), json...), suffix...)
}

在 GoLang playground 上运行此示例

英文:

Use string concatenation:

func addRoot(json string) string {
	return `{ "Employee":` + json + `}`
}

Run an example on the GoLang playground.

Here's the code if you are working with []byte instead of string:

func addRoot(json []byte) []byte {
	const prefix = `{ "Employee":`
	const suffix = `}`
	result := make([]byte, 0, len(prefix)+len(json)+len(suffix))
	return append(append(append(result, prefix...), json...), suffix...)
}

Run this example on the GoLang playground.

答案3

得分: -1

如果你有一个字节切片([]byte)中的一些 JSON 数据,你可以直接添加外部元素,例如(playground):

existingJSON := []byte(`[
      {
         "EmpId":{
            "String":"ABCD",
            "Valid":true
         },
         "Department":{
            "Float64":0,
            "Valid":true
         }
      }
   ]`)
b := bytes.NewBufferString(`{"Employee":`)
b.Write(existingJSON)
b.WriteString(`}`)
fmt.Println(string(b.Bytes()))

如果这不是你要找的,请在问题中提供更多细节(最好提供一个最小可复现示例)。

英文:

If you have some JSON in a byte slice ([]byte) then you can just add the outer element directly - e.g. (playground):

existingJSON := []byte(`[
      {
         "EmpId":{
            "String":"ABCD",
            "Valid":true
         },
         "Department":{
            "Float64":0,
            "Valid":true
         }
      }
   ]`)
b := bytes.NewBufferString(`{"Employee":`)
b.Write(existingJSON)
b.WriteString(`}`)
fmt.Println(string(b.Bytes()))

If this is not what you are looking for please add further details to your question (ideally your attempt as a minimal, reproducible, example)

huangapple
  • 本文由 发表于 2022年9月23日 06:10:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/73821150.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定