@@ -157,15 +157,17 @@ internal class _XMLElement {
157
157
parentElement. children [ key] = ( parentElement. children [ key] ?? [ ] ) + [ element]
158
158
}
159
159
160
- func flatten( ) -> [ String : Any ] {
160
+ func flatten( with charDataKey : String ? = nil ) -> [ String : Any ] {
161
161
var node : [ String : Any ] = attributes
162
162
163
163
for childElement in children {
164
164
for child in childElement. value {
165
- if let content = child. value {
166
- node [ childElement. key] = content
167
- } else if !child. children. isEmpty || !child. attributes. isEmpty {
168
- let newValue = child. flatten ( )
165
+ if !child. children. isEmpty || !child. attributes. isEmpty {
166
+ var newValue = child. flatten ( with: charDataKey)
167
+ if let content = child. value,
168
+ let charDataKey = charDataKey {
169
+ newValue [ charDataKey] = content
170
+ }
169
171
170
172
if let existingValue = node [ childElement. key] {
171
173
if var array = existingValue as? Array < Any > {
@@ -177,6 +179,8 @@ internal class _XMLElement {
177
179
} else {
178
180
node [ childElement. key] = newValue
179
181
}
182
+ } else if let content = child. value {
183
+ node [ childElement. key] = content
180
184
}
181
185
}
182
186
}
@@ -248,12 +252,30 @@ internal class _XMLStackParser: NSObject, XMLParserDelegate {
248
252
var currentElementName : String ?
249
253
var currentElementData = " "
250
254
251
- static func parse( with data: Data ) throws -> [ String : Any ] {
255
+
256
+ /// Parses the XML data and returns a dictionary of the parsed output
257
+ ///
258
+ /// - Parameters:
259
+ /// - data: The Data to be parsed
260
+ /// - charDataToken: The token to key the charData in mixed content elements off of
261
+ /// - Returns: Dictionary of the parsed XML
262
+ /// - Throws: DecodingError if there's an issue parsing the XML
263
+ /// - Note:
264
+ /// When an XML Element has both attributes and child elements, the CharData within the element will be keyed with the `characterDataToken`
265
+ /// The following XML has both attribute data, child elements, and character data:
266
+ /// ```
267
+ /// <SomeElement SomeAttribute="value">
268
+ /// some string value
269
+ /// <SomeOtherElement>valuevalue</SomeOtherElement>
270
+ /// </SomeElement>
271
+ /// ```
272
+ /// The "some string value" will be keyed on "CharData"
273
+ static func parse( with data: Data , charDataToken: String ? = nil ) throws -> [ String : Any ] {
252
274
let parser = _XMLStackParser ( )
253
275
254
276
do {
255
277
if let node = try parser. parse ( with: data) {
256
- return node. flatten ( )
278
+ return node. flatten ( with : charDataToken )
257
279
} else {
258
280
throw DecodingError . dataCorrupted ( DecodingError . Context ( codingPath: [ ] , debugDescription: " The given data could not be parsed into XML. " ) )
259
281
}
0 commit comments