Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encoding a CDATA wrapped object #76

Open
timsearle opened this issue Feb 18, 2019 · 2 comments
Open

Encoding a CDATA wrapped object #76

timsearle opened this issue Feb 18, 2019 · 2 comments
Assignees

Comments

@timsearle
Copy link

timsearle commented Feb 18, 2019

I have a question around producing the following output:

<MsgData><![CDATA[
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="TOKEN">
<someElement>1111.2222.3333.4444</someElement>
<anotherElement>4000000000000065</anotherElement>
<test>31122019</test>
</foo>]]></MsgData>

How can I use XMLEncoder to produce? This element is nested within others but they've been omitted for clarity. All I can currently think of is encode the internal object separately, convert from Data into a String, and then encode with a CDATA encoding strategy.

I'm also slightly confused around how to conditionally use CData encoding on strings without enabling and disabling it on the encoder as I pass. Any thoughts or ideas would be hugely appreciated!

@MaxDesiatov MaxDesiatov self-assigned this Feb 25, 2019
@MaxDesiatov
Copy link
Collaborator

MaxDesiatov commented Feb 25, 2019

Thank you for reporting this @timsearle and sorry for the delayed reply. I'm wondering if implementing some helpers for CDATA in the recently added DynamicNodeEncoding (#70) would be realistic. @JoeMatt would be interesting to hear your thoughts on this if possible 🙏

@timsearle
Copy link
Author

Thanks Max! Just as an update, I'm currently working around this issue using something along the lines of:

struct CDATA<MessageData: Codable & XMLRootKey> {
    let data: MessageData

    init(contents: MessageData) {
        self.data = contents
    }

    func CDATARepresentation() -> String {
        let xmlEncoder = SOAP.encoder()

        guard let data = try? xmlEncoder.encode(data, withRootKey: data.rootKey),
            let result = String(data: data, encoding: .utf8) else {
                return ""
        }

        return "<![CDATA[\(result)]]>"
    }
}

extension CDATA: Codable {
    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        let data = try container.decode(String.self).data(using: .utf8) ?? Data()

        let decoder = SOAP.decoder()
        self.data = try decoder.decode(MessageData.self, from: data)
    }
}

Where SOAP.decoder() is a convenience for returning a special subclass of XMLCoder I've made with some custom encoding strategies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants