dqef7931 2018-09-16 15:48
浏览 97

Golang使用未知密钥解析JSON

I'm trying to unmarshal json with dynamic field keys to the struct That json returned from storcli utility for linux. One part of the code work well, but if json data contains many structs I can't unmarshal it. I think that is because DriveDetailedInformation struct do not have all json tags. Can anybody help me?

package main

import (
    "fmt"
    "encoding/json"
)

type jsonStruct struct {
    Controllers []struct {
        CommandStatus struct {
            Controller  int    `json:"Controller"`
            Status      string `json:"Status"`
            Description string `json:"Description"`
        } `json:"Command Status"`
        ResponseData map[string]*json.RawMessage `json:"Response Data"`
    } `json:"Controllers"`
}

type DriveStruct struct {
    EIDSlt string `json:"EID:Slt"`
    DID    int    `json:"DID"`
    State  string `json:"State"`
    DG     int    `json:"DG"`
    Size   string `json:"Size"`
    Intf   string `json:"Intf"`
    Med    string `json:"Med"`
    SED    string `json:"SED"`
    PI     string `json:"PI"`
    SeSz   string `json:"SeSz"`
    Model  string `json:"Model"`
    Sp     string `json:"Sp"`
}

type DriveDetailedInformation struct {
    DriveState            map[string]DriveStateStruct
    DriveDeviceAttributes map[string]DriveDeviceAttributesStruct
    DrivePoliciesSettings map[string]DrivePoliciesSettingsStruct
    InquiryData           string `json:"Inquiry Data"`
}

type DriveStateStruct struct {
    ShieldCounter            int    `json:"Shield Counter"`
    MediaErrorCount          int    `json:"Media Error Count"`
    OtherErrorCount          int    `json:"Other Error Count"`
    BBMErrorCount            int    `json:"BBM Error Count"`
    DriveTemperature         string `json:"Drive Temperature"`
    PredictiveFailureCount   int    `json:"Predictive Failure Count"`
    SMARTAlertFlaggedByDrive string `json:"S.M.A.R.T alert flagged by drive"`
}

type DriveDeviceAttributesStruct struct {
    SN               string `json:"SN"`
    ManufacturerID   string `json:"Manufacturer Id"`
    ModelNumber      string `json:"Model Number"`
    NANDVendor       string `json:"NAND Vendor"`
    WWN              string `json:"WWN"`
    FirmwareRevision string `json:"Firmware Revision"`
    RawSize          string `json:"Raw size"`
    CoercedSize      string `json:"Coerced size"`
    NonCoercedSize   string `json:"Non Coerced size"`
    DeviceSpeed      string `json:"Device Speed"`
    LinkSpeed        string `json:"Link Speed"`
    NCQSetting       string `json:"NCQ setting"`
    WriteCache       string `json:"Write cache"`
    SectorSize       string `json:"Sector Size"`
    ConnectorName    string `json:"Connector Name"`
}

type DrivePoliciesSettingsStruct struct {
    DrivePosition                            string `json:"Drive position"`
    EnclosurePosition                        int    `json:"Enclosure position"`
    ConnectedPortNumber                      string `json:"Connected Port Number"`
    SequenceNumber                           int    `json:"Sequence Number"`
    CommissionedSpare                        string `json:"Commissioned Spare"`
    EmergencySpare                           string `json:"Emergency Spare"`
    LastPredictiveFailureEventSequenceNumber int    `json:"Last Predictive Failure Event Sequence Number"`
    SuccessfulDiagnosticsCompletionOn        string `json:"Successful diagnostics completion on"`
    SEDCapable                               string `json:"SED Capable"`
    SEDEnabled                               string `json:"SED Enabled"`
    Secured                                  string `json:"Secured"`
    Locked                                   string `json:"Locked"`
    NeedsEKMAttention                        string `json:"Needs EKM Attention"`
    PIEligible                               string `json:"PI Eligible"`
    Certified                                string `json:"Certified"`
    WidePortCapable                          string `json:"Wide Port Capable"`
    PortInformation                          []struct {
        Port       int    `json:"Port"`
        Status     string `json:"Status"`
        Linkspeed  string `json:"Linkspeed"`
        SASAddress string `json:"SAS address"`
    } `json:"Port Information"`
}

var jsonData = `
{
   "Controllers":[
      {
         "Command Status":{
            "Controller":0,
            "Status":"Success",
            "Description":"Show Drive Information Succeeded."
         },
         "Response Data":{
            "Drive /c0/e31/s0":[
               {
                  "EID:Slt":"31:0",
                  "DID":19,
                  "State":"Onln",
                  "DG":0,
                  "Size":"9.094 TB",
                  "Intf":"SATA",
                  "Med":"HDD",
                  "SED":"N",
                  "PI":"N",
                  "SeSz":"512B",
                  "Model":"ST10000DM0004-1ZC101",
                  "Sp":"U"
               }
            ],
            "Drive /c0/e31/s0 - Detailed Information":{
               "Drive /c0/e31/s0 State":{
                  "Shield Counter":0,
                  "Media Error Count":0,
                  "Other Error Count":0,
                  "BBM Error Count":0,
                  "Drive Temperature":" 25C (77.00 F)",
                  "Predictive Failure Count":0,
                  "S.M.A.R.T alert flagged by drive":"No"
               },
               "Drive /c0/e31/s0 Device attributes":{
                  "SN":"            ZA23V0DH",
                  "Manufacturer Id":"ATA     ",
                  "Model Number":"ST10000DM0004-1ZC101",
                  "NAND Vendor":"NA",
                  "WWN":"5000c500a5ad06b6",
                  "Firmware Revision":"DN01    ",
                  "Raw size":"9.095 TB [0x48c400000 Sectors]",
                  "Coerced size":"9.094 TB [0x48c300000 Sectors]",
                  "Non Coerced size":"9.094 TB [0x48c300000 Sectors]",
                  "Device Speed":"6.0Gb/s",
                  "Link Speed":"6.0Gb/s",
                  "NCQ setting":"N/A",
                  "Write cache":"N/A",
                  "Sector Size":"512B",
                  "Connector Name":""
               },
               "Drive /c0/e31/s0 Policies/Settings":{
                  "Drive position":"DriveGroup:0, Span:0, Row:0",
                  "Enclosure position":0,
                  "Connected Port Number":"0(path0) ",
                  "Sequence Number":2,
                  "Commissioned Spare":"No",
                  "Emergency Spare":"No",
                  "Last Predictive Failure Event Sequence Number":0,
                  "Successful diagnostics completion on":"N/A",
                  "SED Capable":"No",
                  "SED Enabled":"No",
                  "Secured":"No",
                  "Locked":"No",
                  "Needs EKM Attention":"No",
                  "PI Eligible":"No",
                  "Certified":"No",
                  "Wide Port Capable":"No",
                  "Port Information":[
                     {
                        "Port":0,
                        "Status":"Active",
                        "Linkspeed":"6.0Gb/s",
                        "SAS address":"0x5003048001927c6c"
                     }
                  ]
               },
               "Inquiry Data":""
            },
            "Drive /c0/e31/s1":[
               {
                  "EID:Slt":"31:1",
                  "DID":20,
                  "State":"Onln",
                  "DG":0,
                  "Size":"9.094 TB",
                  "Intf":"SATA",
                  "Med":"HDD",
                  "SED":"N",
                  "PI":"N",
                  "SeSz":"512B",
                  "Model":"ST10000DM0004-1ZC101",
                  "Sp":"U"
               }
            ],
            "Drive /c0/e31/s1 - Detailed Information":{
               "Drive /c0/e31/s1 State":{
                  "Shield Counter":0,
                  "Media Error Count":0,
                  "Other Error Count":0,
                  "BBM Error Count":0,
                  "Drive Temperature":" 25C (77.00 F)",
                  "Predictive Failure Count":0,
                  "S.M.A.R.T alert flagged by drive":"No"
               },
               "Drive /c0/e31/s1 Device attributes":{
                  "SN":"            ZA23MCVS",
                  "Manufacturer Id":"ATA     ",
                  "Model Number":"ST10000DM0004-1ZC101",
                  "NAND Vendor":"NA",
                  "WWN":"5000c500a5acc582",
                  "Firmware Revision":"DN01    ",
                  "Raw size":"9.095 TB [0x48c400000 Sectors]",
                  "Coerced size":"9.094 TB [0x48c300000 Sectors]",
                  "Non Coerced size":"9.094 TB [0x48c300000 Sectors]",
                  "Device Speed":"6.0Gb/s",
                  "Link Speed":"6.0Gb/s",
                  "NCQ setting":"N/A",
                  "Write cache":"N/A",
                  "Sector Size":"512B",
                  "Connector Name":""
               },
               "Drive /c0/e31/s1 Policies/Settings":{
                  "Drive position":"DriveGroup:0, Span:0, Row:1",
                  "Enclosure position":0,
                  "Connected Port Number":"0(path0) ",
                  "Sequence Number":2,
                  "Commissioned Spare":"No",
                  "Emergency Spare":"No",
                  "Last Predictive Failure Event Sequence Number":0,
                  "Successful diagnostics completion on":"N/A",
                  "SED Capable":"No",
                  "SED Enabled":"No",
                  "Secured":"No",
                  "Locked":"No",
                  "Needs EKM Attention":"No",
                  "PI Eligible":"No",
                  "Certified":"No",
                  "Wide Port Capable":"No",
                  "Port Information":[
                     {
                        "Port":0,
                        "Status":"Active",
                        "Linkspeed":"6.0Gb/s",
                        "SAS address":"0x5003048001927c6d"
                     }
                  ]
               },
               "Inquiry Data":""
            }
         }
      }
   ]
}
`

func main() {
    var f jsonStruct
    err := json.Unmarshal([]byte(jsonData), &f)
    if err != nil {
        fmt.Println("Error parsing JSON: ", err)
    }

    for _, controller := range f.Controllers {
        for k, v := range controller.ResponseData {

            ///THAT IS WORK
            var ds []DriveStruct
            if err := json.Unmarshal(*v, &ds); err == nil {
                fmt.Println(k, ds)

            }

            ///THAT IS NOT WORK WHY?
            var dds DriveDetailedInformation
            if err := json.Unmarshal(*v, &dds); err == nil {
                fmt.Println(k, dds)
            }
        }
    }
}
  • 写回答

1条回答 默认 最新

  • 普通网友 2018-09-17 04:29
    关注

    Because your key value is not correct. Below is the code I modified.

    type DriveDetailedInformation struct {
    DriveState            DriveStateStruct `json:"Drive /c0/e31/s0 State"`
    DriveDeviceAttributes DriveDeviceAttributesStruct `json:"Drive /c0/e31/s0 Device attributes"`
    DrivePoliciesSettings DrivePoliciesSettingsStruct `json:"Drive /c0/e31/s0 Policies/Settings"`
    InquiryData           string `json:"Inquiry Data"`
    }
    
    type DriveDetailedInformation1 struct {
        DriveState            DriveStateStruct `json:"Drive /c0/e31/s1 State"`
        DriveDeviceAttributes DriveDeviceAttributesStruct `json:"Drive /c0/e31/s1 Device attributes"`
        DrivePoliciesSettings DrivePoliciesSettingsStruct `json:"Drive /c0/e31/s1 Policies/Settings"`
        InquiryData           string `json:"Inquiry Data"`
    }
    func main() {
        var f jsonStruct
        err := json.Unmarshal([]byte(jsonData), &f)
        if err != nil {
            fmt.Println("Error parsing JSON: ", err)
        }
    
        for _, controller := range f.Controllers {
            for k, v := range controller.ResponseData {
                switch k {
                case "Drive /c0/e31/s0","Drive /c0/e31/s1":
                    var ds []DriveStruct
                    if err := json.Unmarshal(*v, &ds); err == nil {
                        fmt.Println(k, ds)
                    }
                case "Drive /c0/e31/s1 - Detailed Information":
                    var dds1 DriveDetailedInformation1
                    if err := json.Unmarshal(*v, &dds1); err == nil {
                        fmt.Println(k, dds1)
                    }
                case "Drive /c0/e31/s0 - Detailed Information":
                    var dds DriveDetailedInformation
                    if err := json.Unmarshal(*v, &dds); err == nil {
                        fmt.Println(k, dds)
                    }
                }
            }
        }
    }
    

    I think Response Data can be parsed in a structure.

    评论

报告相同问题?

悬赏问题

  • ¥30 python代码,帮调试
  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条