func sanitizersForAttributeValue(c context) ([]string, error) {
	var elems, attrs []string
	if len(c.element.names) == 0 {
		elems = []string{c.element.name}
	} else {
		elems = c.element.names
	}
	if len(c.attr.names) == 0 {
		attrs = []string{c.attr.name}
	} else {
		attrs = c.attr.names
	}
	var sc0 sanitizationContext
	var elem0, attr0 string
	for i, elem := range elems {
		for j, attr := range attrs {
			sc, err := sanitizationContextForAttrVal(elem, attr, c.linkRel)
			if err != nil {
				if len(elems) == 1 && len(attrs) == 1 {
					return nil, err
				}
				return nil, fmt.Errorf(`conditional branch with {element=%q, attribute=%q} results in sanitization error: %s`, elem, attr, err)
			}
			if i == 0 && j == 0 {
				sc0, elem0, attr0 = sc, elem, attr
				continue
			}
			if sc != sc0 {
				return nil, fmt.Errorf(
					`conditional branches end in different attribute value sanitization contexts: {element=%q, attribute=%q} has sanitization context %q, {element=%q, attribute=%q} has sanitization context %q`,
					elem0, attr0, sc0, elem, attr, sc)
			}
		}
	}
	if sc0.isEnum() && c.attr.value != "" {
		return nil, fmt.Errorf("partial substitutions are disallowed in the %q attribute value context of a %q element", c.attr.name, c.element.name)
	}
	if sc0 == sanitizationContextStyle && c.attr.value != "" {
		if err := validateDoesNotEndsWithCharRefPrefix(c.attr.value); err != nil {
			return nil, fmt.Errorf("action cannot be interpolated into the %q attribute value of this %q element: %s", c.attr.name, c.element.name, err)
		}
	}
	var ret []string
	ret = append(ret, sanitizeHTMLFuncName)
	sanitizer := sc0.sanitizerName()
	if !sc0.isURLorTrustedResourceURL() {
		return reverse(appendIfNotEmpty(ret, sanitizer)), nil
	}
	urlAttrValPrefix := c.attr.value
	if urlAttrValPrefix == "" {
		return reverse(appendIfNotEmpty(ret, normalizeURLFuncName, sanitizer)), nil
	}
	if c.attr.ambiguousValue {
		return nil, fmt.Errorf("actions must not occur after an ambiguous URL prefix in the %q attribute value context of a %q element", c.attr.name, c.element.name)
	}
	validator, ok := urlPrefixValidators[sc0]
	if !ok {
		return nil, fmt.Errorf("cannot validate attribute value prefix %q in the %q sanitization context", c.attr.value, sc0)
	}
	if err := validator(c.attr.value); err != nil {
		return nil, fmt.Errorf("action cannot be interpolated into the %q URL attribute value of this %q element: %s", c.attr.name, c.element.name, err)
	}
	switch {
	case sc0 == sanitizationContextTrustedResourceURL:
		ret = append(ret, queryEscapeURLFuncName, validateTrustedResourceURLSubstitutionFuncName)
	case strings.ContainsAny(urlAttrValPrefix, "#?"):
		ret = append(ret, queryEscapeURLFuncName)
	default:
		ret = append(ret, normalizeURLFuncName)
	}
	return reverse(ret), nil
}
sanitizersForAttributeValue returns a list of names of functions that will be
called in order to sanitize data values found the HTML attribtue value context c.
package template
import (
	"fmt"
	"regexp"
	"strings"
)
func sanitizerForContext(c context) ([]string, error) {
	switch c.state {
	case stateTag, stateAttrName, stateAfterName:
		return nil, fmt.Errorf("actions must not affect element or attribute names")
	case stateHTMLCmt:
		return []string{sanitizeHTMLCommentFuncName}, nil
	}
	if len(c.element.names) == 0 && c.element.name == "" && c.state == stateText {
		return []string{sanitizeHTMLFuncName}, nil
	}
	if c.attr.name != "" || len(c.attr.names) > 0 {
		if c.delim != delimDoubleQuote && c.delim != delimSingleQuote {
			return nil, fmt.Errorf("unquoted attribute values disallowed")
		}
		return sanitizersForAttributeValue(c)
	}
	elementContentSanitizer, err := sanitizerForElementContent(c)
	return appendIfNotEmpty([]string{}, elementContentSanitizer), err
}
func appendIfNotEmpty(slice []string, strings ...string) []string {
	for _, s := range strings {
		if s != "" {
			slice = append(slice, s)
		}
	}
	return slice
}