我有一个很大的Json文件要解析(几MB),并且没有适当的文档。生活艰难。据我所知,文件很容易。但是有些事情我不理解,简单的Codable协议失败了。在数组layers
中,我可以找到三个Layer对象,每个对象都有属性elements
。在elements
中,我可以找到多个elementData
-在第一层中有"ImageID":32dd...
和component
,在第二层和第三层"name":...
和{{1} }。可能会有更多的可能性。我的每一次尝试都以错误结束。
很抱歉,这段代码会持续很长时间,但是我不想删掉重要的部分:
"contours": [...]
如何处理?
答案 0 :(得分:2)
https://app.quicktype.io,正确的json
{ "layers":[
{
"name":"img",
"elements":[
{
"elementData":{
"imageId":"32dd800000002"
},
"transform":{
"xScale":100,
"yScale":100
},
"active":true
},
{
"component":{
"glyphName":"e",
"layerName":"img"
}
},
{
"elementData":{
"composite":{
"builder":{
"builderGroup":{
}
}
}
},
"transform":{
"xOffset":120
},
"nonSpacing":true
}
],
"color":"maroon",
"active":true
},
{
"name":"Black",
"elements":[
{
"component":{
"glyphName":"e",
"layerName":"Black"
}
},
{
"elementData":{
"name":"caron",
"contours":[
{
"nodes":[
"80 577",
"107 549 142 550 167 575 s"
]
}
]
}
}
],
"color":"#00802a"
},
{
"name":"Thin",
"elements":[
{
"component":{
"glyphName":"e",
"layerName":"Thin"
}
},
{
"elementData":{
"name":"caron",
"contours":[
{
"nodes":[
"102 597 s",
"118 580 132 580 148 597 s",
"250 710",
"235 726",
"110 613",
"140 613",
"14 726",
"-1 710"
]
}
]
}
}
],
"color":"#6a8000"
}
]}
解析
struct Welcome: Codable {
let layers: [Layer]
}
struct Layer: Codable {
let name: String
let elements: [Element]
let color: String
let active: Bool?
}
struct Element: Codable {
let elementData: ElementData?
let transform: Transform?
let active: Bool?
let component: Component?
let nonSpacing: Bool?
}
struct Component: Codable {
let glyphName, layerName: String
}
struct ElementData: Codable {
let imageID: String?
let composite: Composite?
let name: String?
let contours: [Contour]?
enum CodingKeys: String, CodingKey {
case imageID = "imageId"
case composite, name, contours
}
}
struct Composite: Codable {
let builder: Builder
}
struct Builder: Codable {
let builderGroup: BuilderGroup
}
struct BuilderGroup: Codable {
}
struct Contour: Codable {
let nodes: [String]
}
struct Transform: Codable {
let xScale, yScale, xOffset: Int?
}
do {
let res = try JSONDecoder().decode(Welcome.self,from:data)
}
catch {
print(error)
}
编辑:
struct Welcome: Codable {
let layers: [Layer]
}
struct Layer: Codable {
let name: String
let elements: [Element]
let color: String
let active: Bool?
}
struct Element: Codable {
let elementData: ElementDataUnion?
let transform: Transform?
let active: Bool?
let component: Component?
let nonSpacing: Bool?
}
struct Component: Codable {
let glyphName, layerName: String
}
enum ElementDataUnion: Codable {
case elementDataClass(ElementDataClass)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if let x = try? container.decode(ElementDataClass.self) {
self = .elementDataClass(x)
return
}
throw DecodingError.typeMismatch(ElementDataUnion.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ElementDataUnion"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .elementDataClass(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
struct ElementDataClass: Codable {
let composite: Composite?
let name: String?
let contours: [Contour]?
}
struct Composite: Codable {
let builder: Builder
}
struct Builder: Codable {
let builderGroup: BuilderGroup
}
struct BuilderGroup: Codable {
}
struct Contour: Codable {
let nodes: [String]
}
struct Transform: Codable {
let xScale, yScale, xOffset: Int?
}
如果您需要elementData
作为字典/字符串、、、、 elements
作为数组/字符串,请使用
struct Welcome: Codable {
let layers: [Layer]
}
struct Layer: Codable {
let name: String
let elements: Elements
let color: String
let active: Bool?
}
enum Elements: Codable {
case elementArray([Element])
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode([Element].self) {
self = .elementArray(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Elements.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Elements"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .elementArray(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
struct Element: Codable {
let component: Component?
let elementData: ElementDataUnion?
}
struct Component: Codable {
let glyphName, layerName: String
}
enum ElementDataUnion: Codable {
case elementDataClass(ElementDataClass)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if let x = try? container.decode(ElementDataClass.self) {
self = .elementDataClass(x)
return
}
throw DecodingError.typeMismatch(ElementDataUnion.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ElementDataUnion"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .elementDataClass(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
struct ElementDataClass: Codable {
let name: String
let contours: [Contour]
}
struct Contour: Codable {
let nodes: [String]
}