@@ -155,7 +155,7 @@ type indentation struct {
155155 level int
156156 hasChild bool
157157 indent string
158- w io.Writer
158+ w io.Writer
159159}
160160
161161func newIndentation (indent string , w io.Writer ) * indentation {
@@ -168,101 +168,139 @@ func newIndentation(indent string, w io.Writer) *indentation {
168168 }
169169}
170170
171- func (i * indentation ) NewLine () {
171+ func (i * indentation ) NewLine () ( err error ) {
172172 if i == nil {
173173 return
174174 }
175- io .WriteString (i .w , "\n " )
175+ _ , err = io .WriteString (i .w , "\n " )
176+ return
176177}
177178
178- func (i * indentation ) Open () {
179+ func (i * indentation ) Open () ( err error ) {
179180 if i == nil {
180181 return
181182 }
182183
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+ }
185187
186188 i .level ++
187189 i .hasChild = false
190+ return
188191}
189192
190- func (i * indentation ) Close () {
193+ func (i * indentation ) Close () ( err error ) {
191194 if i == nil {
192195 return
193196 }
194197 i .level --
195198 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+ }
198202 }
199203 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
200214}
201215
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 ) {
203217 preserveSpaces = calculatePreserveSpaces (n , preserveSpaces )
204218 switch n .Type {
205219 case TextNode :
206- io .WriteString (w , html .EscapeString (n .sanitizedData (preserveSpaces )))
220+ _ , err = io .WriteString (w , html .EscapeString (n .sanitizedData (preserveSpaces )))
207221 return
208222 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 )
212224 return
213225 case CommentNode :
214226 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 )
218228 }
219229 return
220230 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 )
223235 return
224236 case DeclarationNode :
225- io .WriteString (w , "<?" + n .Data )
237+ _ , err = io .WriteString (w , "<?" + n .Data )
238+ if err != nil {
239+ return
240+ }
226241 default :
227- indent .Open ()
242+ if err = indent .Open (); err != nil {
243+ return
244+ }
228245 if n .Prefix == "" {
229- io .WriteString (w , "<" + n .Data )
246+ _ , err = io .WriteString (w , "<" + n .Data )
230247 } 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
232252 }
233253 }
234254
235255 for _ , attr := range n .Attr {
236256 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 )
238258 } 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
240263 }
241264
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+ }
243269 }
244270 if n .Type == DeclarationNode {
245- io .WriteString (w , "?>" )
271+ _ , err = io .WriteString (w , "?>" )
246272 } else {
247273 if n .FirstChild != nil || ! config .emptyElementTagSupport {
248- io .WriteString (w , ">" )
274+ _ , err = io .WriteString (w , ">" )
249275 } else {
250- io .WriteString (w , "/>" )
251- indent .Close ()
276+ _ , err = io .WriteString (w , "/>" )
277+ if err != nil {
278+ return
279+ }
280+ err = indent .Close ()
252281 return
253282 }
254283 }
284+ if err != nil {
285+ return
286+ }
255287 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+ }
257292 }
258293 if n .Type != DeclarationNode {
259- indent .Close ()
294+ if err = indent .Close (); err != nil {
295+ return
296+ }
260297 if n .Prefix == "" {
261- fmt .Fprintf (w , "</%s>" , n .Data )
298+ _ , err = fmt .Fprintf (w , "</%s>" , n .Data )
262299 } else {
263- fmt .Fprintf (w , "</%s:%s>" , n .Prefix , n .Data )
300+ _ , err = fmt .Fprintf (w , "</%s:%s>" , n .Prefix , n .Data )
264301 }
265302 }
303+ return
266304}
267305
268306// OutputXML returns the text that including tags name.
@@ -281,15 +319,15 @@ func (n *Node) OutputXMLWithOptions(opts ...OutputOption) string {
281319}
282320
283321// 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 {
285323 if self {
286- n .WriteWithOptions (writer , WithOutputSelf ())
324+ return n .WriteWithOptions (writer , WithOutputSelf ())
287325 }
288- n .WriteWithOptions (writer )
326+ return n .WriteWithOptions (writer )
289327}
290328
291329// 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 ) {
293331 config := & outputConfiguration {}
294332 // Set the options
295333 for _ , opt := range opts {
@@ -300,13 +338,18 @@ func (n *Node) WriteWithOptions(writer io.Writer, opts ...OutputOption) {
300338 b := bufio .NewWriter (writer )
301339 defer b .Flush ()
302340
341+ ident := newIndentation (config .useIndentation , b )
303342 if config .printSelf && n .Type != DocumentNode {
304- outputXML (b , n , preserveSpaces , config , newIndentation ( config . useIndentation , b ) )
343+ err = outputXML (b , n , preserveSpaces , config , ident )
305344 } else {
306345 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+ }
308350 }
309351 }
352+ return
310353}
311354
312355// AddAttr adds a new attribute specified by 'key' and 'val' to a node 'n'.
0 commit comments