@@ -155,7 +155,7 @@ type indentation struct {
155
155
level int
156
156
hasChild bool
157
157
indent string
158
- w io.Writer
158
+ w io.Writer
159
159
}
160
160
161
161
func newIndentation (indent string , w io.Writer ) * indentation {
@@ -168,101 +168,139 @@ func newIndentation(indent string, w io.Writer) *indentation {
168
168
}
169
169
}
170
170
171
- func (i * indentation ) NewLine () {
171
+ func (i * indentation ) NewLine () ( err error ) {
172
172
if i == nil {
173
173
return
174
174
}
175
- io .WriteString (i .w , "\n " )
175
+ _ , err = io .WriteString (i .w , "\n " )
176
+ return
176
177
}
177
178
178
- func (i * indentation ) Open () {
179
+ func (i * indentation ) Open () ( err error ) {
179
180
if i == nil {
180
181
return
181
182
}
182
183
183
- io .WriteString (i .w , "\n " )
184
- io .WriteString (i .w , strings .Repeat (i .indent , i .level ))
184
+ if err = i .writeIndent (); err != nil {
185
+ return
186
+ }
185
187
186
188
i .level ++
187
189
i .hasChild = false
190
+ return
188
191
}
189
192
190
- func (i * indentation ) Close () {
193
+ func (i * indentation ) Close () ( err error ) {
191
194
if i == nil {
192
195
return
193
196
}
194
197
i .level --
195
198
if i .hasChild {
196
- io .WriteString (i .w , "\n " )
197
- io .WriteString (i .w , strings .Repeat (i .indent , i .level ))
199
+ if err = i .writeIndent (); err != nil {
200
+ return
201
+ }
198
202
}
199
203
i .hasChild = true
204
+ return
205
+ }
206
+
207
+ func (i * indentation ) writeIndent () (err error ) {
208
+ _ , err = io .WriteString (i .w , "\n " )
209
+ if err != nil {
210
+ return
211
+ }
212
+ _ , err = io .WriteString (i .w , strings .Repeat (i .indent , i .level ))
213
+ return
200
214
}
201
215
202
- func outputXML (w io.Writer , n * Node , preserveSpaces bool , config * outputConfiguration , indent * indentation ) {
216
+ func outputXML (w io.Writer , n * Node , preserveSpaces bool , config * outputConfiguration , indent * indentation ) ( err error ) {
203
217
preserveSpaces = calculatePreserveSpaces (n , preserveSpaces )
204
218
switch n .Type {
205
219
case TextNode :
206
- io .WriteString (w , html .EscapeString (n .sanitizedData (preserveSpaces )))
220
+ _ , err = io .WriteString (w , html .EscapeString (n .sanitizedData (preserveSpaces )))
207
221
return
208
222
case CharDataNode :
209
- io .WriteString (w , "<![CDATA[" )
210
- io .WriteString (w , n .Data )
211
- io .WriteString (w , "]]>" )
223
+ _ , err = fmt .Fprintf (w , "<![CDATA[%v]]>" , n .Data )
212
224
return
213
225
case CommentNode :
214
226
if ! config .skipComments {
215
- io .WriteString (w , "<!--" )
216
- io .WriteString (w , n .Data )
217
- io .WriteString (w , "-->" )
227
+ _ , err = fmt .Fprintf (w , "<!--%v-->" , n .Data )
218
228
}
219
229
return
220
230
case NotationNode :
221
- indent .NewLine ()
222
- fmt .Fprintf (w , "<!%s>" , n .Data )
231
+ if err = indent .NewLine (); err != nil {
232
+ return
233
+ }
234
+ _ , err = fmt .Fprintf (w , "<!%s>" , n .Data )
223
235
return
224
236
case DeclarationNode :
225
- io .WriteString (w , "<?" + n .Data )
237
+ _ , err = io .WriteString (w , "<?" + n .Data )
238
+ if err != nil {
239
+ return
240
+ }
226
241
default :
227
- indent .Open ()
242
+ if err = indent .Open (); err != nil {
243
+ return
244
+ }
228
245
if n .Prefix == "" {
229
- io .WriteString (w , "<" + n .Data )
246
+ _ , err = io .WriteString (w , "<" + n .Data )
230
247
} else {
231
- fmt .Fprintf (w , "<%s:%s" , n .Prefix , n .Data )
248
+ _ , err = fmt .Fprintf (w , "<%s:%s" , n .Prefix , n .Data )
249
+ }
250
+ if err != nil {
251
+ return
232
252
}
233
253
}
234
254
235
255
for _ , attr := range n .Attr {
236
256
if attr .Name .Space != "" {
237
- fmt .Fprintf (w , ` %s:%s=` , attr .Name .Space , attr .Name .Local )
257
+ _ , err = fmt .Fprintf (w , ` %s:%s=` , attr .Name .Space , attr .Name .Local )
238
258
} else {
239
- fmt .Fprintf (w , ` %s=` , attr .Name .Local )
259
+ _ , err = fmt .Fprintf (w , ` %s=` , attr .Name .Local )
260
+ }
261
+ if err != nil {
262
+ return
240
263
}
241
264
242
- fmt .Fprintf (w , `"%v"` , html .EscapeString (attr .Value ))
265
+ _ , err = fmt .Fprintf (w , `"%v"` , html .EscapeString (attr .Value ))
266
+ if err != nil {
267
+ return
268
+ }
243
269
}
244
270
if n .Type == DeclarationNode {
245
- io .WriteString (w , "?>" )
271
+ _ , err = io .WriteString (w , "?>" )
246
272
} else {
247
273
if n .FirstChild != nil || ! config .emptyElementTagSupport {
248
- io .WriteString (w , ">" )
274
+ _ , err = io .WriteString (w , ">" )
249
275
} else {
250
- io .WriteString (w , "/>" )
251
- indent .Close ()
276
+ _ , err = io .WriteString (w , "/>" )
277
+ if err != nil {
278
+ return
279
+ }
280
+ err = indent .Close ()
252
281
return
253
282
}
254
283
}
284
+ if err != nil {
285
+ return
286
+ }
255
287
for child := n .FirstChild ; child != nil ; child = child .NextSibling {
256
- outputXML (w , child , preserveSpaces , config , indent )
288
+ err = outputXML (w , child , preserveSpaces , config , indent )
289
+ if err != nil {
290
+ return
291
+ }
257
292
}
258
293
if n .Type != DeclarationNode {
259
- indent .Close ()
294
+ if err = indent .Close (); err != nil {
295
+ return
296
+ }
260
297
if n .Prefix == "" {
261
- fmt .Fprintf (w , "</%s>" , n .Data )
298
+ _ , err = fmt .Fprintf (w , "</%s>" , n .Data )
262
299
} else {
263
- fmt .Fprintf (w , "</%s:%s>" , n .Prefix , n .Data )
300
+ _ , err = fmt .Fprintf (w , "</%s:%s>" , n .Prefix , n .Data )
264
301
}
265
302
}
303
+ return
266
304
}
267
305
268
306
// OutputXML returns the text that including tags name.
@@ -281,15 +319,15 @@ func (n *Node) OutputXMLWithOptions(opts ...OutputOption) string {
281
319
}
282
320
283
321
// Write writes xml to given writer.
284
- func (n * Node ) Write (writer io.Writer , self bool ) {
322
+ func (n * Node ) Write (writer io.Writer , self bool ) error {
285
323
if self {
286
- n .WriteWithOptions (writer , WithOutputSelf ())
324
+ return n .WriteWithOptions (writer , WithOutputSelf ())
287
325
}
288
- n .WriteWithOptions (writer )
326
+ return n .WriteWithOptions (writer )
289
327
}
290
328
291
329
// WriteWithOptions writes xml with given options to given writer.
292
- func (n * Node ) WriteWithOptions (writer io.Writer , opts ... OutputOption ) {
330
+ func (n * Node ) WriteWithOptions (writer io.Writer , opts ... OutputOption ) ( err error ) {
293
331
config := & outputConfiguration {}
294
332
// Set the options
295
333
for _ , opt := range opts {
@@ -300,13 +338,18 @@ func (n *Node) WriteWithOptions(writer io.Writer, opts ...OutputOption) {
300
338
b := bufio .NewWriter (writer )
301
339
defer b .Flush ()
302
340
341
+ ident := newIndentation (config .useIndentation , b )
303
342
if config .printSelf && n .Type != DocumentNode {
304
- outputXML (b , n , preserveSpaces , config , newIndentation ( config . useIndentation , b ) )
343
+ err = outputXML (b , n , preserveSpaces , config , ident )
305
344
} else {
306
345
for n := n .FirstChild ; n != nil ; n = n .NextSibling {
307
- outputXML (b , n , preserveSpaces , config , newIndentation (config .useIndentation , b ))
346
+ err = outputXML (b , n , preserveSpaces , config , ident )
347
+ if err != nil {
348
+ break
349
+ }
308
350
}
309
351
}
352
+ return
310
353
}
311
354
312
355
// AddAttr adds a new attribute specified by 'key' and 'val' to a node 'n'.
0 commit comments