@@ -6,11 +6,25 @@ public extension Node {
66 /// This method searches for a child element with the given name and attempts to decode it.
77 /// If the element is missing, it returns `nil`.
88 ///
9- /// - Parameter name: The name of the element to decode; either a `String` or an `ExpandedName` .
9+ /// - Parameter name: The name of the element to decode.
1010 /// - Returns: A decoded instance of `T`, or `nil` if the element is not present.
1111 /// - Throws: `XMLElementCodableError.invalidFormat` if the element cannot be parsed.
1212 ///
13- func decode< T: XMLElementDecodable > ( elementName name: any ElementName ) throws -> T ? {
13+ func decode< T: XMLElementDecodable > ( elementName name: String ) throws -> T ? {
14+ guard let element = self [ element: name] else { return nil }
15+ return try T . init ( from: element)
16+ }
17+
18+ /// Decodes an optional XML element into the specified type.
19+ ///
20+ /// This method searches for a child element with the given expanded name and attempts to decode it.
21+ /// If the element is missing, it returns `nil`.
22+ ///
23+ /// - Parameter name: The expanded name of the element to decode.
24+ /// - Returns: A decoded instance of `T`, or `nil` if the element is not present.
25+ /// - Throws: `XMLElementCodableError.invalidFormat` if the element cannot be parsed.
26+ ///
27+ func decode< T: XMLElementDecodable > ( elementName name: ExpandedName ) throws -> T ? {
1428 guard let element = self [ element: name] else { return nil }
1529 return try T . init ( from: element)
1630 }
@@ -19,30 +33,70 @@ public extension Node {
1933 ///
2034 /// If the element is missing, this method *throws an error*.
2135 ///
22- /// - Parameter name: The name of the element to decode; either a `String` or an `ExpandedName` .
36+ /// - Parameter name: The name of the element to decode.
2337 /// - Returns: A decoded instance of `T`.
2438 /// - Throws:
2539 /// - `XMLElementCodableError.elementMissing` if the element is missing.
2640 /// - `XMLElementCodableError.invalidFormat` if the element cannot be parsed.
2741 ///
28- func decode< T: XMLElementDecodable > ( elementName name: any ElementName ) throws -> T {
42+ func decode< T: XMLElementDecodable > ( elementName name: String ) throws -> T {
2943 guard let element: T = try decode ( elementName: name) else { throw XMLElementCodableError . elementMissing ( name) }
3044 return element
3145 }
3246
47+ /// Decodes an XML element into the specified type.
48+ ///
49+ /// If the element is missing, this method *throws an error*.
50+ ///
51+ /// - Parameter name: The expanded name of the element to decode.
52+ /// - Returns: A decoded instance of `T`.
53+ /// - Throws:
54+ /// - `XMLElementCodableError.elementMissing` if the element is missing.
55+ /// - `XMLElementCodableError.invalidFormat` if the element cannot be parsed.
56+ ///
57+ func decode< T: XMLElementDecodable > ( elementName name: ExpandedName ) throws -> T {
58+ guard let element: T = try decode ( elementName: name) else { throw XMLElementCodableError . expandedElementMissing ( name) }
59+ return element
60+ }
61+
3362 /// Decodes an array of XML elements into the specified type.
3463 ///
3564 /// This method searches for all child elements matching the given name and decodes them.
3665 /// If a `containerName` is provided, it looks inside that container element first.
3766 ///
3867 /// - Parameters:
39- /// - name: The name of the elements to decode; either a `String` or an `ExpandedName` .
68+ /// - name: The name of the elements to decode.
4069 /// - containerName: The optional container element name. If provided, the method searches inside this container.
4170 /// - Returns: An array of decoded values.
4271 /// - Throws:
4372 /// - `XMLElementCodableError.invalidFormat` if any element cannot be parsed.
4473 ///
45- func decode< T: XMLElementDecodable > ( elementName name: any ElementName , containedIn containerName: ElementName ? = nil ) throws -> [ T ] {
74+ func decode< T: XMLElementDecodable > ( elementName name: String , containedIn containerName: String ? = nil ) throws -> [ T ] {
75+ let parent : Node
76+ if let containerName {
77+ guard let container = self [ element: containerName] else {
78+ return [ ]
79+ }
80+ parent = container
81+ } else {
82+ parent = self
83+ }
84+ return try parent [ elements: name] . map { try T . init ( from: $0) }
85+ }
86+
87+ /// Decodes an array of XML elements into the specified type.
88+ ///
89+ /// This method searches for all child elements matching the given expanded name and decodes them.
90+ /// If a `containerName` is provided, it looks inside that container element first.
91+ ///
92+ /// - Parameters:
93+ /// - name: The expanded name of the elements to decode.
94+ /// - containerName: The optional container element name. If provided, the method searches inside this container.
95+ /// - Returns: An array of decoded values.
96+ /// - Throws:
97+ /// - `XMLElementCodableError.invalidFormat` if any element cannot be parsed.
98+ ///
99+ func decode< T: XMLElementDecodable > ( elementName name: ExpandedName , containedIn containerName: ExpandedName ? = nil ) throws -> [ T ] {
46100 let parent : Node
47101 if let containerName {
48102 guard let container = self [ element: containerName] else {
@@ -63,23 +117,58 @@ public extension Node {
63117 ///
64118 /// - Parameters:
65119 /// - item: The value to encode.
66- /// - name: The name of the XML element to create; either a `String` or an `ExpandedName` .
120+ /// - name: The name of the XML element to create.
67121 ///
68- func encode< T: XMLElementEncodable > ( _ item: T ? , elementName name: any ElementName ) {
122+ func encode< T: XMLElementEncodable > ( _ item: T ? , elementName name: String ) {
69123 guard let item else { return }
70124 item. encode ( to: addElement ( name) )
71125 }
72126
127+ /// Encodes an optional value as an XML element.
128+ ///
129+ /// If the provided value is `nil`, no element is added.
130+ ///
131+ /// - Parameters:
132+ /// - item: The value to encode.
133+ /// - name: The expanded name of the XML element to create.
134+ ///
135+ func encode< T: XMLElementEncodable > ( _ item: T ? , elementName name: ExpandedName ) {
136+ guard let item else { return }
137+ item. encode ( to: addElement ( name) )
138+ }
139+
140+ /// Encodes an array of values as XML elements.
141+ ///
142+ /// This method creates an element for each value in `items`. If `containerName` is provided, all elements are wrapped inside that container.
143+ ///
144+ /// - Parameters:
145+ /// - items: The array of values to encode. If this is empty, this method does nothing.
146+ /// - name: The name of each XML element.
147+ /// - containerName: An optional container element name. If provided, the elements are placed inside this container.
148+ ///
149+ func encode< T: XMLElementEncodable > ( _ items: [ T ] , elementName name: String , containedIn containerName: String ? = nil ) {
150+ guard items. isEmpty == false else { return }
151+ let parent : Node
152+ if let containerName {
153+ parent = addElement ( containerName)
154+ } else {
155+ parent = self
156+ }
157+ for item in items {
158+ parent. encode ( item, elementName: name)
159+ }
160+ }
161+
73162 /// Encodes an array of values as XML elements.
74163 ///
75164 /// This method creates an element for each value in `items`. If `containerName` is provided, all elements are wrapped inside that container.
76165 ///
77166 /// - Parameters:
78167 /// - items: The array of values to encode. If this is empty, this method does nothing.
79- /// - name: The name of each XML element; either a `String` or an `ExpandedName` .
80- /// - containerName: An optional container element name; either a `String` or an `ExpandedName` . If provided, the elements are placed inside this container.
168+ /// - name: The expanded name of each XML element.
169+ /// - containerName: An optional container element name. If provided, the elements are placed inside this container.
81170 ///
82- func encode< T: XMLElementEncodable > ( _ items: [ T ] , elementName name: any ElementName , containedIn containerName: ( any ElementName ) ? = nil ) {
171+ func encode< T: XMLElementEncodable > ( _ items: [ T ] , elementName name: ExpandedName , containedIn containerName: ExpandedName ? = nil ) {
83172 guard items. isEmpty == false else { return }
84173 let parent : Node
85174 if let containerName {
0 commit comments