Search code examples
swiftswxmlhash

Deserialisation error with SWXMLHash


I have the following XML structure (this is a stripped-down example):

<Root>
    <SomeData>Some value</SomeData>
    ...
    <ClientInfo>
        <Client>MD</Client>
        <Name>Massive Dynamic</Name>
    </ClientInfo>
</Root>

With the following model:

struct ClientInfo : XMLElementDeserializable {
    let Client : String
    let Name : String

    static func deserialize(_ node: XMLIndexer) throws -> ClientInfo {
        return try ClientInfo(
            Client: node["Client"].value(),
            Name: node["Name"].value()
        )
    }
}

And I'm trying to parse the XML as follows:

let clientInfo : ClientInfo? = try? xml.children[0]["ClientInfo"].value()

However, it keeps failing with an ImplementationIsMissing error as if my custom deserialize function doesn't exist.

What gives?


Solution

  • You're almost there, just one small mistype... instead of XMLElementDeserializable, you should use XMLIndexerDeserializable.

    The below works for me in a Playground:

    import SWXMLHash
    
    let xmlData = "<Root>" +
    "<SomeData>Some value</SomeData>" +
    "    <ClientInfo>" +
    "       <Client>MD</Client>" +
    "       <Name>Massive Dynamic</Name>" +
    "   </ClientInfo>" +
    "</Root>"
    
    let xml = SWXMLHash.parse(xmlData)
    
    struct ClientInfo : XMLIndexerDeserializable {
        let Client: String
        let Name: String
    
        static func deserialize(_ node: XMLIndexer) throws -> ClientInfo {
            return try ClientInfo(
                Client: node["Client"].value(),
                Name: node["Name"].value()
            )
        }
    }
    
    let info: ClientInfo? = try? xml.children[0]["ClientInfo"].value()
    

    The distinction between those two gets a little confusing and it definitely needs to be improved in the library. The gist is that XMLElementDeserializable is for standalone types (e.g. strings, ints, dates, etc.) that don't have children nodes.