diff --git a/Sources/XMLCoder/Auxiliaries/KeyedStorage.swift b/Sources/XMLCoder/Auxiliaries/KeyedStorage.swift index 49a82d0d..740455fa 100644 --- a/Sources/XMLCoder/Auxiliaries/KeyedStorage.swift +++ b/Sources/XMLCoder/Auxiliaries/KeyedStorage.swift @@ -83,7 +83,7 @@ extension KeyedStorage where Key == String, Value == Box { } else if let value = element.value { result.append(StringBox(value), at: element.key) } else { - result.append(NullBox(), at: element.key) + result.append(SingleKeyedBox(key: element.key, element: NullBox()), at: element.key) } return result diff --git a/Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift b/Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift index cbf42eb2..e236db91 100644 --- a/Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift +++ b/Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift @@ -79,6 +79,10 @@ struct XMLKeyedDecodingContainer: KeyedDecodingContainerProtocol { let box = elements.first ?? attributes.first + if let singleKeyed = box as? SingleKeyedBox { + return singleKeyed.element.isNull + } + return box?.isNull ?? true } @@ -232,14 +236,26 @@ extension XMLKeyedDecodingContainer { let keyString = key.stringValue.isEmpty ? "value" : key.stringValue let value = keyedBox.elements[keyString] if !value.isEmpty { - return value + return value.map { + if let singleKeyed = $0 as? SingleKeyedBox { + return singleKeyed.element + } else { + return $0 + } + } } else if let value = keyedBox.value { return [value] } else { return [] } } else { - return keyedBox.elements[key.stringValue] + return keyedBox.elements[key.stringValue].map { + if let singleKeyed = $0 as? SingleKeyedBox { + return singleKeyed.element + } else { + return $0 + } + } } } diff --git a/Tests/XMLCoderTests/NestedChoiceTests.swift b/Tests/XMLCoderTests/NestedChoiceTests.swift index 4810c454..44344c49 100644 --- a/Tests/XMLCoderTests/NestedChoiceTests.swift +++ b/Tests/XMLCoderTests/NestedChoiceTests.swift @@ -227,6 +227,50 @@ class NestedChoiceTests: XCTestCase { XCTAssertEqual(result, expected) } + func testNestedEnumsWithEmptyStruct() throws { + let xml = """ + +

+

+ + 1518 + I am answering it again. + + + 431 + A Word About Wake Times + +

+

+ + 1519 + I am answering it again. + +
+

+
+ """ + let result = try XMLDecoder().decode(Container.self, from: xml.data(using: .utf8)!) + let expected = Container( + paragraphs: [ + Paragraph( + entries: [ + .br(Break()), + .run(Run(id: 1518, text: "I am answering it again.")), + .properties(Properties(id: 431, title: "A Word About Wake Times")), + ] + ), + Paragraph( + entries: [ + .run(Run(id: 1519, text: "I am answering it again.")), + .br(Break()), + ] + ), + ] + ) + XCTAssertEqual(result, expected) + } + func testNestedEnumsRoundTrip() throws { let original = Container( paragraphs: [