Custom XML Parser - что делать, если некоторые ключи не существуют? - PullRequest
0 голосов
/ 06 июня 2018

Хорошо, я работаю Реализация пользовательского декодера в Swift 4 , и из этого следует, что анализатор ищет эти ключи в XML:

struct RSSChannel: Codable {
    var title: String
    var pubDate: Date
    var link: URL
    var description: String
    var items: [RSSItem]
    enum CodingKeys: String, CodingKey {
        case title, pubDate, link, description
        case items = "item"
    }
}'

(я не писалвот, это GitHub, так что я борюсь здесь) -

Мне нужно знать, как остановить ошибку синтаксического анализатора, когда в ленте нет ключа, то есть даты публикации.В классе XMLDecoder есть все эти декодеры:

 public func decode(_ type: UInt.Type) throws -> UInt {
        try expectNonNull(UInt.self)
        return try self.unbox(self.storage.topContainer, as: UInt.self)!
    }

    public func decode(_ type: UInt8.Type) throws -> UInt8 {
        try expectNonNull(UInt8.self)
        return try self.unbox(self.storage.topContainer, as: UInt8.self)!
    }

    public func decode(_ type: UInt16.Type) throws -> UInt16 {
        try expectNonNull(UInt16.self)
        return try self.unbox(self.storage.topContainer, as: UInt16.self)!
    }

    public func decode(_ type: UInt32.Type) throws -> UInt32 {
        try expectNonNull(UInt32.self)
        return try self.unbox(self.storage.topContainer, as: UInt32.self)!
    }

    public func decode(_ type: UInt64.Type) throws -> UInt64 {
        try expectNonNull(UInt64.self)
        return try self.unbox(self.storage.topContainer, as: UInt64.self)!
    }

    public func decode(_ type: Float.Type) throws -> Float {
        try expectNonNull(Float.self)
        return try self.unbox(self.storage.topContainer, as: Float.self)!
    }

    public func decode(_ type: Double.Type) throws -> Double {
        try expectNonNull(Double.self)

На самом деле:

  public func decode<T : Decodable>(_ type: T.Type, forKey key: Key) throws -> T {
        guard let entry = self.container[key.stringValue] else {

            print("SKYaw")
            throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\")."))
        }

        self.decoder.codingPath.append(key)
        defer { self.decoder.codingPath.removeLast() }

        guard let value = try self.decoder.unbox(entry, as: type) else {
            throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead."))
        }

        return value
    }

Связка из них.Кто-нибудь сталкивался с проблемами, когда он говорит "Нет ключа, связанного с ключом" / выдает ошибку?Как я могу обойти это с этой библиотекой?

1 Ответ

0 голосов
/ 07 июня 2018

В библиотеке XMLParsing вам нужно будет сделать свойство необязательным, если оно может отсутствовать в данных.

Это похоже на поведение, которое вы найдете в JSONDecoder от Apple, если значение несуществует в JSON.


В вашем примере вы упомянули, что pubDate может не существовать в вашем XML, поэтому обновленная структура канала будет выглядеть следующим образом:

struct RSSChannel: Codable {
    var title: String
    var pubDate: Date?
    var link: URL
    var description: String
    var items: [RSSItem]

    enum CodingKeys: String, CodingKey {
        case title, pubDate, link, description
        case items = "item"
    }
}

Так что в тех случаях, когда pubDate существует в вашем XML, в этом свойстве будет указана дата.В тех случаях, когда ключ не существует в XML, значение для pubDate будет nil.

Вы можете сделать столько свойств, сколько захотите, в своей структуре необязательными, и все они будут следовать этомушаблон.

...