diff --git a/Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift b/Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift
index 0d2437de..a9710354 100644
--- a/Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift
+++ b/Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift
@@ -275,9 +275,14 @@ extension XMLKeyedDecodingContainer {
}
// If we are looking at a coding key value intrinsic where the expected type is `String` and
- // the value is empty, return `""`.
+ // the value is empty, return CDATA if present otherwise `""`.
if strategy(key) != .attribute, elements.isEmpty, attributes.isEmpty, type == String.self, key.stringValue == "", let emptyString = "" as? T {
- return emptyString
+ let cdata = container.withShared { keyedBox in
+ keyedBox.elements["#CDATA"].map {
+ return ($0 as? KeyedBox)?.value ?? $0
+ }
+ }.first
+ return ((cdata as? StringBox)?.unboxed as? T) ?? emptyString
}
switch strategy(key) {
diff --git a/Tests/XMLCoderTests/CDATAMixedUsageTest.swift b/Tests/XMLCoderTests/CDATAMixedUsageTest.swift
new file mode 100644
index 00000000..1d55bcf2
--- /dev/null
+++ b/Tests/XMLCoderTests/CDATAMixedUsageTest.swift
@@ -0,0 +1,36 @@
+//
+// CDATAMixedUsageTest.swift
+// XMLCoderTests
+//
+// Created by Johan Kool on 15/03/2023.
+//
+
+import XCTest
+import XMLCoder
+
+final class CDATAMixedUsageTest: XCTestCase {
+ private struct DataEntry: Codable, Equatable {
+ let value: String
+ enum CodingKeys: String, CodingKey {
+ case value = ""
+ }
+ }
+
+ private struct Container: Codable, Equatable {
+ let data: [DataEntry]
+ }
+
+ private let xml =
+ """
+
+
+ bla bla
+
+ """.data(using: .utf8)!
+
+ func testXMLWithMixedCDATAUsage() throws {
+ let decoder = XMLDecoder()
+ let result = try decoder.decode(Container.self, from: xml)
+ XCTAssertEqual(result, Container(data: [.init(value: "lorem ipsum"), .init(value: "bla bla")]))
+ }
+}
diff --git a/XMLCoder.xcodeproj/project.pbxproj b/XMLCoder.xcodeproj/project.pbxproj
index 06ebbd00..2f8404d5 100644
--- a/XMLCoder.xcodeproj/project.pbxproj
+++ b/XMLCoder.xcodeproj/project.pbxproj
@@ -33,6 +33,7 @@
B5647C4824897589001F6507 /* Element.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5647C4724897589001F6507 /* Element.swift */; };
B5E67535238B4960006C8548 /* IntOrString.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E67534238B4960006C8548 /* IntOrString.swift */; };
B5F74472233F74E400BBDB15 /* RootLevelAttributeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F74471233F74E400BBDB15 /* RootLevelAttributeTest.swift */; };
+ C7D23FB529C23A5F00CAD394 /* CDATAMixedUsageTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7D23FB429C23A5F00CAD394 /* CDATAMixedUsageTest.swift */; };
D11E094623491BCE00C24DCB /* DoubleBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D11E094523491BCE00C24DCB /* DoubleBox.swift */; };
D11E094A234924C500C24DCB /* ValueBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D11E0949234924C500C24DCB /* ValueBox.swift */; };
D18FBFB82348FAE500FA4F65 /* EscapedCharactersTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D18FBFB72348FAE500FA4F65 /* EscapedCharactersTest.swift */; };
@@ -184,6 +185,7 @@
B5647C4724897589001F6507 /* Element.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Element.swift; sourceTree = ""; };
B5E67534238B4960006C8548 /* IntOrString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntOrString.swift; sourceTree = ""; };
B5F74471233F74E400BBDB15 /* RootLevelAttributeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootLevelAttributeTest.swift; sourceTree = ""; };
+ C7D23FB429C23A5F00CAD394 /* CDATAMixedUsageTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CDATAMixedUsageTest.swift; sourceTree = ""; };
D11E094523491BCE00C24DCB /* DoubleBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleBox.swift; sourceTree = ""; };
D11E0949234924C500C24DCB /* ValueBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValueBox.swift; sourceTree = ""; };
D18FBFB72348FAE500FA4F65 /* EscapedCharactersTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EscapedCharactersTest.swift; sourceTree = ""; };
@@ -500,6 +502,7 @@
D1A1838724842D710058E66D /* AdvancedFeatures */,
D1A1839324842D710058E66D /* EndToEnd */,
D1A1838324842C920058E66D /* CDATATest.swift */,
+ C7D23FB429C23A5F00CAD394 /* CDATAMixedUsageTest.swift */,
D1A1838024842C7D0058E66D /* PrettyPrintTest.swift */,
OBJ_68 /* BenchmarkTests.swift */,
OBJ_88 /* ClassTests.swift */,
@@ -833,6 +836,7 @@
D1A183C324842DE80058E66D /* AttributedIntrinsicTest.swift in Sources */,
D1A183C424842DE80058E66D /* MixedChoiceAndNonChoiceTests.swift in Sources */,
OBJ_256 /* URLTests.swift in Sources */,
+ C7D23FB529C23A5F00CAD394 /* CDATAMixedUsageTest.swift in Sources */,
OBJ_257 /* UnkeyedIntTests.swift in Sources */,
D1A183B824842DE20058E66D /* CDTest.swift in Sources */,
OBJ_258 /* UnkeyedTests.swift in Sources */,