Skip to content

Commit 666227d

Browse files
authored
Fix mixed CDATA usage (#261)
Fixes #260
1 parent c10bb50 commit 666227d

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,14 @@ extension XMLKeyedDecodingContainer {
275275
}
276276

277277
// If we are looking at a coding key value intrinsic where the expected type is `String` and
278-
// the value is empty, return `""`.
278+
// the value is empty, return CDATA if present otherwise `""`.
279279
if strategy(key) != .attribute, elements.isEmpty, attributes.isEmpty, type == String.self, key.stringValue == "", let emptyString = "" as? T {
280-
return emptyString
280+
let cdata = container.withShared { keyedBox in
281+
keyedBox.elements["#CDATA"].map {
282+
return ($0 as? KeyedBox)?.value ?? $0
283+
}
284+
}.first
285+
return ((cdata as? StringBox)?.unboxed as? T) ?? emptyString
281286
}
282287

283288
switch strategy(key) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//
2+
// CDATAMixedUsageTest.swift
3+
// XMLCoderTests
4+
//
5+
// Created by Johan Kool on 15/03/2023.
6+
//
7+
8+
import XCTest
9+
import XMLCoder
10+
11+
final class CDATAMixedUsageTest: XCTestCase {
12+
private struct DataEntry: Codable, Equatable {
13+
let value: String
14+
enum CodingKeys: String, CodingKey {
15+
case value = ""
16+
}
17+
}
18+
19+
private struct Container: Codable, Equatable {
20+
let data: [DataEntry]
21+
}
22+
23+
private let xml =
24+
"""
25+
<container>
26+
<data><![CDATA[lorem ipsum]]></data>
27+
<data>bla bla</data>
28+
</container>
29+
""".data(using: .utf8)!
30+
31+
func testXMLWithMixedCDATAUsage() throws {
32+
let decoder = XMLDecoder()
33+
let result = try decoder.decode(Container.self, from: xml)
34+
XCTAssertEqual(result, Container(data: [.init(value: "lorem ipsum"), .init(value: "bla bla")]))
35+
}
36+
}

XMLCoder.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
B5647C4824897589001F6507 /* Element.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5647C4724897589001F6507 /* Element.swift */; };
3434
B5E67535238B4960006C8548 /* IntOrString.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E67534238B4960006C8548 /* IntOrString.swift */; };
3535
B5F74472233F74E400BBDB15 /* RootLevelAttributeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F74471233F74E400BBDB15 /* RootLevelAttributeTest.swift */; };
36+
C7D23FB529C23A5F00CAD394 /* CDATAMixedUsageTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7D23FB429C23A5F00CAD394 /* CDATAMixedUsageTest.swift */; };
3637
D11E094623491BCE00C24DCB /* DoubleBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D11E094523491BCE00C24DCB /* DoubleBox.swift */; };
3738
D11E094A234924C500C24DCB /* ValueBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D11E0949234924C500C24DCB /* ValueBox.swift */; };
3839
D18FBFB82348FAE500FA4F65 /* EscapedCharactersTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D18FBFB72348FAE500FA4F65 /* EscapedCharactersTest.swift */; };
@@ -184,6 +185,7 @@
184185
B5647C4724897589001F6507 /* Element.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Element.swift; sourceTree = "<group>"; };
185186
B5E67534238B4960006C8548 /* IntOrString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntOrString.swift; sourceTree = "<group>"; };
186187
B5F74471233F74E400BBDB15 /* RootLevelAttributeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootLevelAttributeTest.swift; sourceTree = "<group>"; };
188+
C7D23FB429C23A5F00CAD394 /* CDATAMixedUsageTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CDATAMixedUsageTest.swift; sourceTree = "<group>"; };
187189
D11E094523491BCE00C24DCB /* DoubleBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleBox.swift; sourceTree = "<group>"; };
188190
D11E0949234924C500C24DCB /* ValueBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValueBox.swift; sourceTree = "<group>"; };
189191
D18FBFB72348FAE500FA4F65 /* EscapedCharactersTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EscapedCharactersTest.swift; sourceTree = "<group>"; };
@@ -500,6 +502,7 @@
500502
D1A1838724842D710058E66D /* AdvancedFeatures */,
501503
D1A1839324842D710058E66D /* EndToEnd */,
502504
D1A1838324842C920058E66D /* CDATATest.swift */,
505+
C7D23FB429C23A5F00CAD394 /* CDATAMixedUsageTest.swift */,
503506
D1A1838024842C7D0058E66D /* PrettyPrintTest.swift */,
504507
OBJ_68 /* BenchmarkTests.swift */,
505508
OBJ_88 /* ClassTests.swift */,
@@ -833,6 +836,7 @@
833836
D1A183C324842DE80058E66D /* AttributedIntrinsicTest.swift in Sources */,
834837
D1A183C424842DE80058E66D /* MixedChoiceAndNonChoiceTests.swift in Sources */,
835838
OBJ_256 /* URLTests.swift in Sources */,
839+
C7D23FB529C23A5F00CAD394 /* CDATAMixedUsageTest.swift in Sources */,
836840
OBJ_257 /* UnkeyedIntTests.swift in Sources */,
837841
D1A183B824842DE20058E66D /* CDTest.swift in Sources */,
838842
OBJ_258 /* UnkeyedTests.swift in Sources */,

0 commit comments

Comments
 (0)