英文:
Making minimal modification to JSON data without a structure in golang
问题
我有一个以JSON格式的solr响应,看起来像这样:
{
  "responseHeader": {
    "status": 0,
    "QTime": 0,
    "params": {
      "q": "solo",
      "wt": "json"
    }
  },
  "response": {
    "numFound": 2,
    "start": 0,
    "docs": [
      {
          <大型嵌套的JSON元素>
      },
      {
          <大型嵌套的JSON元素>
      }
    ]
  }
}
现在,在我的Golang应用程序中,我想快速删除"responseHeader",以便只返回"response"。我该如何做到这一点而不创建大型结构?
编辑 1
evanmcdonnal的答案是解决这个问题的方法,但有一些小的拼写错误,这是我最终使用的代码:
var temp map[string]interface{}
if err := json.Unmarshal(body, &temp); err != nil {
    panic(err.Error())
}
result, err := json.Marshal(temp["response"])
英文:
I have a solr response in JSON format which looks like this:
 {
  "responseHeader": {
    "status": 0,
    "QTime": 0,
    "params": {
      "q": "solo",
      "wt": "json"
    }
  },
  "response": {
    "numFound": 2,
    "start": 0,
    "docs": [
      {
          <Large nested JSON element>
      },
      {
          <Large nested JSON element>
      }
    ]
  }
}
Now, in my Golang app, I would like to quickly remove the "responseHeader" so that I can return the "response" alone. How can I do this without creating large structures?
Edit 1
The answer by evanmcdonnal was the solution to this problem, but it had some minor typos, this is what I ended up using:
var temp map[string]interface{}
if err := json.Unmarshal(body, &temp); err != nil {
    panic(err.Error())
}
result, err := json.Marshal(temp["response"])
答案1
得分: 5
以下是如何快速简单地完成这个任务的一个非常简短的示例。步骤如下:将数据解析为通用的map[string]interface{},然后假设没有错误,只对你想要的内部对象进行编组。
var temp := &map[string]interface{}
if err := json.Unmarshal(input, temp); err != nil {
     return err;
}
return json.Marshal(temp["response"])
英文:
Here's a really brief example of how to do this quickly and easily. The steps are; unmarshal into the universal map[string]interface{} then, assuming no errors, marshal only the inner object which you want.
var temp := &map[string]interface{}
if err := json.Unmarshal(input, temp); err != nil {
     return err;
}
return json.Marshal(temp["response"])
答案2
得分: 0
我写了一个名为ujson的包,可以在不解组JSON文档的情况下执行通用转换。
在Go Playground上运行:https://play.golang.org/p/RHlqJPeUEkz
input := []byte(`
{
  "responseHeader": {
    "status": 0,
    "QTime": 0,
    "params": {
      "q": "solo",
      "wt": "json"
    }
  },
  "response": {
    "numFound": 2,
    "start": 0,
    "docs": [
      { "name": "foo" },
      { "name": "bar" }
    ]
  }
}`)
blacklistFields := [][]byte{
	[]byte("\"responseHeader\""), // 注意引号
}
b := make([]byte, 0, 1024)
err := ujson.Walk(input, func(_ int, key, value []byte) bool {
	for _, blacklist := range blacklistFields {
		if bytes.Equal(key, blacklist) {
			// 从输出中删除键和值
			return false
		}
	}
	// 写入输出
	if len(b) != 0 && ujson.ShouldAddComma(value, b[len(b)-1]) {
		b = append(b, ',')
	}
	if len(key) > 0 {
		b = append(b, key...)
		b = append(b, ':')
	}
	b = append(b, value...)
	return true
})
if err != nil {
	panic(err)
}
fmt.Printf("%s", b)
// 输出:{"response":{"numFound":2,"start":0,"docs":[{"name":"foo"},{"name":"bar"}]}}
你可以在博客文章中阅读更多相关信息。我将答案放在这里,以防其他人需要。
英文:
I wrote a package µjson to do exactly that: performing generic transformations on JSON documents without unmarshalling them.
input := []byte(`
{
  "responseHeader": {
    "status": 0,
    "QTime": 0,
    "params": {
      "q": "solo",
      "wt": "json"
    }
  },
  "response": {
    "numFound": 2,
    "start": 0,
    "docs": [
      { "name": "foo" },
      { "name": "bar" }
    ]
  }
}`)
blacklistFields := [][]byte{
	[]byte(`"responseHeader"`), // note the quotes
}
b := make([]byte, 0, 1024)
err := ujson.Walk(input, func(_ int, key, value []byte) bool {
	for _, blacklist := range blacklistFields {
		if bytes.Equal(key, blacklist) {
			// remove the key and value from the output
			return false
		}
	}
	// write to output
	if len(b) != 0 && ujson.ShouldAddComma(value, b[len(b)-1]) {
		b = append(b, ',')
	}
	if len(key) > 0 {
		b = append(b, key...)
		b = append(b, ':')
	}
	b = append(b, value...)
	return true
})
if err != nil {
	panic(err)
}
fmt.Printf("%s", b)
// Output: {"response":{"numFound":2,"start":0,"docs":[{"name":"foo"},{"name":"bar"}]}}
You can read more about it on the blog post. I put the answer here just in case someone else might need it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论