@@ -174,6 +174,19 @@ open class XMLEncoder {
174174 case custom( ( Encoder ) -> Bool )
175175 }
176176
177+ /// The strategy to use when encoding lists.
178+ public enum ListEncodingStrategy {
179+ /// Preserves the type structure. The CodingKey of the List will be used as
180+ /// the tag for each individual item. This is the default strategy.
181+ case preserveStructure
182+
183+ /// Places the individual items of a list within the specified tag and the
184+ /// CodingKey of the List becomes a single outer tag containing all items.
185+ /// Useful for when you want the XML to have this structure but you don't
186+ /// want the type structure to contain this additional wrapping layer.
187+ case expandListWithItemTag( String )
188+ }
189+
177190 /// The output format to produce. Defaults to `[]`.
178191 open var outputFormatting : OutputFormatting = [ ]
179192
@@ -195,6 +208,9 @@ open class XMLEncoder {
195208 /// The strategy to use in encoding strings. Defaults to `.deferredToString`.
196209 open var stringEncodingStrategy : StringEncodingStrategy = . deferredToString
197210
211+ /// The strategy to use in encoding lists. Defaults to `.preserveStructure`.
212+ open var listEncodingStrategy : ListEncodingStrategy = . preserveStructure
213+
198214 /// Contextual user-provided information for use during encoding.
199215 open var userInfo : [ CodingUserInfoKey : Any ] = [ : ]
200216
@@ -206,6 +222,7 @@ open class XMLEncoder {
206222 let keyEncodingStrategy : KeyEncodingStrategy
207223 let attributeEncodingStrategy : AttributeEncodingStrategy
208224 let stringEncodingStrategy : StringEncodingStrategy
225+ let listEncodingStrategy : ListEncodingStrategy
209226 let userInfo : [ CodingUserInfoKey : Any ]
210227 }
211228
@@ -217,6 +234,7 @@ open class XMLEncoder {
217234 keyEncodingStrategy: keyEncodingStrategy,
218235 attributeEncodingStrategy: attributeEncodingStrategy,
219236 stringEncodingStrategy: stringEncodingStrategy,
237+ listEncodingStrategy: listEncodingStrategy,
220238 userInfo: userInfo)
221239 }
222240
@@ -317,8 +335,18 @@ internal class _XMLEncoder: Encoder {
317335 // If an existing unkeyed container was already requested, return that one.
318336 let topContainer : NSMutableArray
319337 if self . canEncodeNewValue {
320- // We haven't yet pushed a container at this level; do so here.
321- topContainer = self . storage. pushUnkeyedContainer ( )
338+ switch options. listEncodingStrategy {
339+ case . preserveStructure:
340+ // We haven't yet pushed a container at this level; do so here.
341+ topContainer = self . storage. pushUnkeyedContainer ( )
342+ case . expandListWithItemTag( let itemTag) :
343+ // create an outer keyed container, with a new array as
344+ // its sole entry
345+ let outerContainer = self . storage. pushKeyedContainer ( )
346+ let array = NSMutableArray ( )
347+ outerContainer [ itemTag] = array
348+ topContainer = array
349+ }
322350 } else {
323351 guard let container = self . storage. containers. last as? NSMutableArray else {
324352 preconditionFailure ( " Attempt to push new unkeyed encoding container when already previously encoded at this path. " )
0 commit comments