CoreOffice / XMLCoder

Easy XML parsing using Codable protocols in Swift
https://coreoffice.github.io/XMLCoder/
MIT License
795 stars 107 forks source link

Help with mix of attributes and elements #212

Closed transat closed 3 years ago

transat commented 3 years ago

I'm having trouble decoding the following XML structure:

let sourceXML = """
<album>
    <details title="Helpless" artist="The Beatless" />
    <files>
        <file fileName="file A.wav" trackNum="1"></file>
        <file fileName="file B.wav" trackNum="2"></file>
        <file fileName="file C.wav" trackNum="3"></file>
    </files>
</album>
"""

struct Album: Codable {
    let details: Details
    let files: Files

    enum CodingKeys: String, CodingKey {
        case details
        case files
    }

    init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            details = try container.decode(Details.self, forKey: .details)
            files = try container.decode(Files.self, forKey: .files)
    }
}

struct Details: Codable, DynamicNodeDecoding, DynamicNodeEncoding{
    let title: String
    let artist: String

    enum CodingKeys: String, CodingKey {
        case title
        case artist
    }

    static func nodeDecoding(for key: CodingKey) -> XMLDecoder.NodeDecoding {
        return .attribute
    }

    static func nodeEncoding(for key: CodingKey) -> XMLEncoder.NodeEncoding {
        return .attribute
    }
}

struct Files: Codable {
    let files: [File]

    enum CodingKeys: String, CodingKey {
        case files
    }
}

struct File: Codable, DynamicNodeDecoding, DynamicNodeEncoding {
    let fileName: String
    let trackNum: Int

    enum CodingKeys: String, CodingKey {
        case fileName
        case trackNum
    }

    static func nodeDecoding(for key: CodingKey) -> XMLDecoder.NodeDecoding {
        return .attribute
    }

    static func nodeEncoding(for key: CodingKey) -> XMLEncoder.NodeEncoding {
        return .attribute
    }
}

let album = try! XMLDecoder().decode(Album.self, from: Data(sourceXML.utf8))

With the above code I can only read the top level parameters but not the array of files. Any tips?

transat commented 3 years ago

Ah. All good! Got it working.