func appendWithoutDuplicates(target []*html.Node, nodes []*html.Node) []*html.Node {
	for _, n := range nodes {
		if !isInSlice(target, n) {
			target = append(target, n)
		}
	}
	return target
}
Appends the new nodes to the target slice, making sure no duplicate is added.
There is no check to the original state of the target slice, so it may still
contain duplicates. The target slice is returned because append() may create
a new underlying array.
package goquery
import (
	"bytes"
	"golang.org/x/net/html"
)
var nodeNames = []string{
	html.ErrorNode:    "#error",
	html.TextNode:     "#text",
	html.DocumentNode: "#document",
	html.CommentNode:  "#comment",
}
func NodeName(s *Selection) string {
	if s.Length() == 0 {
		return ""
	}
	switch n := s.Get(0); n.Type {
	case html.ElementNode, html.DoctypeNode:
		return n.Data
	default:
		if n.Type >= 0 && int(n.Type) < len(nodeNames) {
			return nodeNames[n.Type]
		}
		return ""
	}
}
func OuterHtml(s *Selection) (string, error) {
	var buf bytes.Buffer
	if s.Length() == 0 {
		return "", nil
	}
	n := s.Get(0)
	if err := html.Render(&buf, n); err != nil {
		return "", err
	}
	return buf.String(), nil
}
func getChildren(n *html.Node) (result []*html.Node) {
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		result = append(result, c)
	}
	return result
}
func sliceContains(container []*html.Node, contained *html.Node) bool {
	for _, n := range container {
		if nodeContains(n, contained) {
			return true
		}
	}
	return false
}
func nodeContains(container *html.Node, contained *html.Node) bool {
	for contained = contained.Parent; contained != nil; contained = contained.Parent {
		if container == contained {
			return true
		}
	}
	return false
}
func isInSlice(slice []*html.Node, node *html.Node) bool {
	return indexInSlice(slice, node) > -1
}
func indexInSlice(slice []*html.Node, node *html.Node) int {
	if node != nil {
		for i, n := range slice {
			if n == node {
				return i
			}
		}
	}
	return -1
}