CoreOffice / XMLCoder

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

[Attributes Encodage] Encoding an Attribute doesn't work anymore ! #231

Closed ThePredators closed 2 years ago

ThePredators commented 2 years ago

Hello,

I tried to encode a structure that has a attribute but it seems it doesn't work. It encode elements but no attributes.

How can I make this work ?

public struct Coordinate {

    /// attribute : datum
    public let datum: String = "test123"

    /// Latitude
    public let latitude: Double?

    /// Latitude
    public let longitude: Double?

    public init(latitude: Double?, longitude: Double?) {
        self.latitude = latitude
        self.longitude = longitude
    }
}

// MARK: codable implementation
extension Coordinate: Codable, DynamicNodeEncoding, DynamicNodeDecoding {

    enum CoordinateCodingKeys: String, CodingKey {
        case datum
        case latitude = "Lat"
        case longitude = "Lon"
    }

    public static func nodeDecoding(for key: CodingKey) -> XMLDecoder.NodeDecoding {
        switch key {
        case CoordinateCodingKeys.latitude: return .element
        case CoordinateCodingKeys.longitude: return .element
        default: return .attribute
        }
    }

    public static func nodeEncoding(for key: CodingKey) -> XMLEncoder.NodeEncoding {
        switch key {
        case CoordinateCodingKeys.latitude: return .element
        case CoordinateCodingKeys.longitude: return .element
        default: return .attribute
        }    
  }
}

when I call this :

    let xmlEncoder = XMLEncoder()
    xmlEncoder.keyEncodingStrategy = XMLEncoder.KeyEncodingStrategy.capitalized
    xmlEncoder.outputFormatting = [.prettyPrinted]

    let coordinate = Coordinate(latitude: 38.5, longitude: 77.2)
    let data = try xmlEncoder.encode(coordinate, withRootKey: "Coordinate")
    let xmlStr = String(data: data!, encoding: .utf8)

The content of xmlStr is :

  <Coordinate>
      <Lat>38.5</Lat>
      <Lon>77.2</Lon>
  </Coordinate>

I don't understand why the attribute datum is not set !

Thanks for help.

ThePredators commented 2 years ago

I managed to make it work, but find out a bug :)

when using option : xmlEncoder.keyEncodingStrategy = XMLEncoder.KeyEncodingStrategy.capitalized

the attribute is capitalized like an element.

<Coordinate Datum="wgs84">
    <Lat>38.5</Lat>
    <Lon>77.2</Lon>
</Coordinate>
MaxDesiatov commented 2 years ago

when using option : xmlEncoder.keyEncodingStrategy = XMLEncoder.KeyEncodingStrategy.capitalized

the attribute is capitalized like an element.

Thanks for reporting. This is the intended behavior. "Keys" means both elements and attributes, depending on context.