XMLCoder icon indicating copy to clipboard operation
XMLCoder copied to clipboard

decoder.shouldProcessNamespaces doesn't work for DynamicNodeDecoding?

Open Maxatma opened this issue 5 years ago • 0 comments

Seems like

<?xml version="1.0" encoding="UTF-8"?>
<foo s:name="MY NAME IS WHO" s:id="123">456</foo>

decoder.shouldProcessNamespaces doesn't work for DynamicNodeDecoding attributes:

func testParse() {

struct Foo: Codable, DynamicNodeDecoding {
            let name, id: String
            let value: String
            
            enum CodingKeys: String, CodingKey {
                case name, id
                case value = ""
            }
            
            static func nodeDecoding(for key: CodingKey) -> XMLDecoder.NodeDecoding {
                switch key {
                case CodingKeys.name, CodingKeys.id:
                    return .attribute
                default:
                    return .element
                }
            }
        }
        
        guard let data = str.data(using: .utf8) else { return }
        let decoder = XMLDecoder()
        decoder.shouldProcessNamespaces = true
        
        let response = try! decoder.decode(Foo.self, from: data)
        print("response is ", response)
        XCTAssert(response != nil)
    }

this will produce: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "name", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "name", intValue: nil)], debugDescription: "No attribute found for key CodingKeys(stringValue: \"name\", intValue: nil) (\"name\").", underlyingError: nil))

Only workaround is doing it like that:

  func testParse() {
                
        struct Foo: Codable, DynamicNodeDecoding {
            let name, id: String
            let value: String
            
            enum CodingKeys: String, CodingKey {
                case name = "s:name"
                case id = "s:id"
                case value = ""
            }
            
            static func nodeDecoding(for key: CodingKey) -> XMLDecoder.NodeDecoding {
                switch key {
                case CodingKeys.name, CodingKeys.id:
                    return .attribute
                default:
                    return .element
                }
            }
        }
        
        guard let data = str.data(using: .utf8) else { return }
        let decoder = XMLDecoder()
        decoder.shouldProcessNamespaces = true
        
        let response = try! decoder.decode(Foo.self, from: data)
        print("response is ", response)
        XCTAssert(response != nil)
    }

Maxatma avatar Jan 11 '21 11:01 Maxatma