...

Source file src/github.com/clbanning/mxj/v2/escapechars.go

Documentation: github.com/clbanning/mxj/v2

     1  // Copyright 2016 Charles Banning. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file
     4  
     5  package mxj
     6  
     7  import (
     8  	"bytes"
     9  )
    10  
    11  var xmlEscapeChars bool
    12  
    13  // XMLEscapeChars(true) forces escaping invalid characters in attribute and element values.
    14  // NOTE: this is brute force with NO interrogation of '&' being escaped already; if it is
    15  // then '&' will be re-escaped as '&'.
    16  //
    17  /*
    18  	The values are:
    19  	"   "
    20  	'   '
    21  	<   &lt;
    22  	>   &gt;
    23  	&   &amp;
    24  */
    25  //
    26  // Note: if XMLEscapeCharsDecoder(true) has been called - or the default, 'false,' value
    27  // has been toggled to 'true' - then XMLEscapeChars(true) is ignored.  If XMLEscapeChars(true)
    28  // has already been called before XMLEscapeCharsDecoder(true), XMLEscapeChars(false) is called
    29  // to turn escape encoding on mv.Xml, etc., to prevent double escaping ampersands, '&'.
    30  func XMLEscapeChars(b ...bool) {
    31  	var bb bool
    32  	if len(b) == 0 {
    33  		bb = !xmlEscapeChars
    34  	} else {
    35  		bb = b[0]
    36  	}
    37  	if bb == true && xmlEscapeCharsDecoder == false {
    38  		xmlEscapeChars = true
    39  	} else {
    40  		xmlEscapeChars = false
    41  	}
    42  }
    43  
    44  // Scan for '&' first, since 's' may contain "&amp;" that is parsed to "&amp;amp;"
    45  // - or "&lt;" that is parsed to "&amp;lt;".
    46  var escapechars = [][2][]byte{
    47  	{[]byte(`&`), []byte(`&amp;`)},
    48  	{[]byte(`<`), []byte(`&lt;`)},
    49  	{[]byte(`>`), []byte(`&gt;`)},
    50  	{[]byte(`"`), []byte(`&quot;`)},
    51  	{[]byte(`'`), []byte(`&apos;`)},
    52  }
    53  
    54  func escapeChars(s string) string {
    55  	if len(s) == 0 {
    56  		return s
    57  	}
    58  
    59  	b := []byte(s)
    60  	for _, v := range escapechars {
    61  		n := bytes.Count(b, v[0])
    62  		if n == 0 {
    63  			continue
    64  		}
    65  		b = bytes.Replace(b, v[0], v[1], n)
    66  	}
    67  	return string(b)
    68  }
    69  
    70  // per issue #84, escape CharData values from xml.Decoder
    71  
    72  var xmlEscapeCharsDecoder bool
    73  
    74  // XMLEscapeCharsDecoder(b ...bool) escapes XML characters in xml.CharData values
    75  // returned by Decoder.Token.  Thus, the internal Map values will contain escaped
    76  // values, and you do not need to set XMLEscapeChars for proper encoding.
    77  //
    78  // By default, the Map values have the non-escaped values returned by Decoder.Token.
    79  // XMLEscapeCharsDecoder(true) - or, XMLEscapeCharsDecoder() - will toggle escape
    80  // encoding 'on.'
    81  //
    82  // Note: if XMLEscapeCharDecoder(true) is call then XMLEscapeChars(false) is
    83  // called to prevent re-escaping the values on encoding using mv.Xml, etc.
    84  func XMLEscapeCharsDecoder(b ...bool) {
    85  	if len(b) == 0 {
    86  		xmlEscapeCharsDecoder = !xmlEscapeCharsDecoder
    87  	} else {
    88  		xmlEscapeCharsDecoder = b[0]
    89  	}
    90  	if xmlEscapeCharsDecoder == true && xmlEscapeChars == true {
    91  		xmlEscapeChars = false
    92  	}
    93  }
    94  

View as plain text