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
Specify starting node for decoding #71
Comments
Hi @Eitot, thank you for the suggestions. This somewhat overlaps with #10 as far as I understand. We do have in mind a new API for resolving some of the problems with mapping different structures, but it doesn't cover this specific case. Maybe you could suggest some to way to tie that in? XPath is a very interesting idea, I wonder how difficult it would be to implement something like that 🤔 |
I wonder if we could make struct RSSFeed: Decodable {
let channel: String
enum CodingKeys: String, CodingKey {
case channel = "channel/title"
}
} CC @regexident as he has a lot of experience with |
To be honest, I have no idea how to implement this. JSONDecoder and PropertyListDecoder have the same shortcoming. They require an I am looking for a solution that keeps the code generation intact, while allowing for a straightforward model declaration. Essentially, I just want to declare this: struct RSSFeed: Decodable {
let title: String
} At the moment I have to implement a struct RSSFeed: Decodable {
let title: String
private enum CodingKeys: String, CodingKey {
case channel
case title
}
init(from decoder: Decoder) throws {
let channel = try decoder.container(keyedBy: CodingKeys.self)
let values = try channel.nestedContainer(keyedBy: CodingKeys.self, forKey: .channel)
title = try values.decode(String.self, forKey: .title)
}
} Bear in mind, this is just a simple example. RSS is of course a lot more extensive than this. Perhaps it would be enough to add an optional let decoder = XMLDecoder()
decoder.startingNode = "channel" // or "/rss/channel"
let feed = try decoder.decode(RSSFeed.self, from: data) |
Ok, I see. Thank you for clarifying @Eitot. My initial understanding was that you were looking for a way to "skip" elements in general at any stage during decoding, no just the initial element. Specifying just the starting node does make sense. In your case specifying But it looks like a work around does exist if I understand correctly and it's not that problematic at the moment? Unfortunately, we still have a few higher priority issues, the top one being ordered encoding. If you know there's a lightweight XPath implementation for Swift we could incorporate somehow, please let me know. This would probably make the starting node API much easier to implement. |
Indeed, it is not a problem, just… inelegant. After all, this is how JSONDecoder works too. I’d be happy if this is implemented at some point. 👍 |
This doesn't sound worth it, it's not that arduous to define the whole structure. |
Perhaps I am overlooking this, but I think it would be useful if the starting node could be specified in some way, perhaps via XPath. While trying to implement an RSS feed, I found that I either have to implement the parent node to get to the child nodes I am interested in or write my own
init(from decoder: Decoder)
.For example:
To get to the
title
node, I need to implement a type for thechannel
node as well:The text was updated successfully, but these errors were encountered: