草庐IT

json - 如何在 Go 中导航具有未知结构的嵌套 json?

coder 2024-07-11 原文

我正在尝试从 Go Lang 中的深层嵌套 json 数据中解析和获取选定数据。我在浏览结构和访问数据时遇到问题。数据太深太复杂,无法使用 Go 中的先验已知结构进行解析。 这是文件的 URL: - https://www.data.gouv.fr/api/1/datasets/?format=csv&page=0&page_size=20

我用 map 接口(interface)做了一些解析并使用了一个 json 字符串:

resultdata := map[string]interface {}

json.Unmarshal([]byte(inputbytestring), &resultdata) //Inputstring is the string containing the JSON data of the above URL

问题:

  • 如何将 resultdata 转换为(字符串的)映射,以便我可以使用可用于映射的方法?
  • JSON 数据是嵌套的并且有多个级别。如何访问较低级别的 JSON 字段?是否可以递归地解码数据?

最佳答案

一旦您将数据作为map[string]接口(interface){},您就可以使用类型断言获取较低级别的数据。

https://blog.golang.org/json-and-go 上有关于如何执行此操作的很好的解释。

这是一个让您了解大部分情况的示例:

https://play.golang.org/p/P8cGP1mTDmD

主要包

import (
    "encoding/json"
    "fmt"
    "log"
)

func main() {
    jsonData := `{
    "string": "string_value",
    "number": 123.45,
    "js_array": ["a", "b", "c"],
    "integer": 678,
    "subtype": {
        "number_array": [1, 2, 3]
      }
    }`

    m := map[string]interface{}{}
    err := json.Unmarshal([]byte(jsonData), &m)
    if err != nil {
        log.Fatal(err)
    }

    for key, value := range m {
        switch v := value.(type) {
        case int:
            fmt.Printf("Key: %s, Integer: %d\n", key, v)
        case float64:
            fmt.Printf("Key: %s, Float: %v\n", key, v)
        case string:
            fmt.Printf("Key: %s, String: %s\n", key, v)
        case map[string]interface{}:
            fmt.Printf("Key: %s, Subtype: %+v\n", key, v)
        case []interface{}:
            //TODO: Read through each item in the interface and work out what type it is.
            fmt.Printf("Key: %s, []interface: %v\n", key, v)
        default:
            fmt.Printf("Key: %s, unhandled type: %+v\n", key, v)
        }
    }
}

或者 https://mholt.github.io/json-to-go/在将 JSON 数据示例转换为可用于编码的 Go 结构方面做得不错。

把这个例子放进去,我得到了一些还不错的东西。

type AutoGenerated struct {
    Data []struct {
        Acronym     interface{}   `json:"acronym"`
        Badges      []interface{} `json:"badges"`
        CreatedAt   string        `json:"created_at"`
        Deleted     interface{}   `json:"deleted"`
        Description string        `json:"description"`
        Extras      struct {
        } `json:"extras"`
        Frequency     string      `json:"frequency"`
        FrequencyDate interface{} `json:"frequency_date"`
        ID            string      `json:"id"`
        LastModified  string      `json:"last_modified"`
        LastUpdate    string      `json:"last_update"`
        License       string      `json:"license"`
        Metrics       struct {
            Discussions    int `json:"discussions"`
            Followers      int `json:"followers"`
            Issues         int `json:"issues"`
            NbHits         int `json:"nb_hits"`
            NbUniqVisitors int `json:"nb_uniq_visitors"`
            NbVisits       int `json:"nb_visits"`
            Reuses         int `json:"reuses"`
            Views          int `json:"views"`
        } `json:"metrics"`
        Organization struct {
            Acronym       string `json:"acronym"`
            Class         string `json:"class"`
            ID            string `json:"id"`
            Logo          string `json:"logo"`
            LogoThumbnail string `json:"logo_thumbnail"`
            Name          string `json:"name"`
            Page          string `json:"page"`
            Slug          string `json:"slug"`
            URI           string `json:"uri"`
        } `json:"organization"`
        Owner     interface{} `json:"owner"`
        Page      string      `json:"page"`
        Private   bool        `json:"private"`
        Resources []struct {
            Checksum struct {
                Type  string `json:"type"`
                Value string `json:"value"`
            } `json:"checksum"`
            CreatedAt   string      `json:"created_at"`
            Description interface{} `json:"description"`
            Extras      struct {
            } `json:"extras"`
            Filesize     int    `json:"filesize"`
            Filetype     string `json:"filetype"`
            Format       string `json:"format"`
            ID           string `json:"id"`
            LastModified string `json:"last_modified"`
            Latest       string `json:"latest"`
            Metrics      struct {
                NbHits         int `json:"nb_hits"`
                NbUniqVisitors int `json:"nb_uniq_visitors"`
                NbVisits       int `json:"nb_visits"`
                Views          int `json:"views"`
            } `json:"metrics"`
            Mime       string `json:"mime"`
            PreviewURL string `json:"preview_url"`
            Published  string `json:"published"`
            Title      string `json:"title"`
            Type       string `json:"type"`
            URL        string `json:"url"`
        } `json:"resources"`
        Slug             string        `json:"slug"`
        Spatial          interface{}   `json:"spatial"`
        Tags             []interface{} `json:"tags"`
        TemporalCoverage interface{}   `json:"temporal_coverage"`
        Title            string        `json:"title"`
        URI              string        `json:"uri"`
    } `json:"data"`
    Facets struct {
        Format [][]interface{} `json:"format"`
    } `json:"facets"`
    NextPage     string      `json:"next_page"`
    Page         int         `json:"page"`
    PageSize     int         `json:"page_size"`
    PreviousPage interface{} `json:"previous_page"`
    Total        int         `json:"total"`
}

关于json - 如何在 Go 中导航具有未知结构的嵌套 json?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53997328/

有关json - 如何在 Go 中导航具有未知结构的嵌套 json?的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  4. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  5. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  6. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  7. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  8. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  9. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  10. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

随机推荐