How can I add a non-escaped string as a plaintext node or as an attribute value?

106 Views Asked by At

I am trying to use a string containing a ' character as an attribute value. However, ' is always replaced with '. Is there a way around this? Since the value is enclosed with ", ' wouldn't necessarily have to be escaped, would it? The same happens when I try to add a plain text html node.

package main

import (
    "os"
    "strings"

    "github.com/PuerkitoBio/goquery"
    "golang.org/x/net/html"
)

var htmlString = `<div class="catch-me-if-you-can">‍♂️</div>`

func main() {
    qHtml, err := goquery.NewDocumentFromReader(strings.NewReader(htmlString))
    if err != nil {
        panic(err)
    }

    n := &html.Node{
        Type: html.ElementNode,
        Data: "zombie-hunter",
        Attr: []html.Attribute{
            {Key: "meta", Val: "{name: 'RedEye!', equipment: 'Baseball Bat'}"},
        },
    }

    qHtml.Find(`div`).First().ReplaceWithNodes(n)

    goquery.Render(os.Stdout, qHtml.Contents())
}

Output:

<html><head></head><body><zombie-hunter meta="{name: &#39;RedEye!&#39;, equipment: &#39;Baseball Bat&#39;}"></zombie-hunter></body></html>
1

There are 1 best solutions below

1
On

No, it is not (easily) possible as goquery relies on golang.org/x/net/html.Render() for HTML output and that hardcodes text-node escaping.

// no goquery involved here...
func main() {
    w := new(strings.Builder)
    n := &html.Node{
        Type: html.ElementNode,
        Data: "zombie-hunter",
        Attr: []html.Attribute{
            {Key: "meta", Val: "{name: 'RedEye!', equipment: 'Baseball Bat'}"},
        },
    }
    html.Render(w, n)
    fmt.Println(w.String())
}
<zombie-hunter meta="{name: &#39;RedEye!&#39;, equipment: &#39;Baseball Bat&#39;}"></zombie-hunter>

If you really need it you'd probably need to re-implement html.Render() (and related functions) to not escape this one character and patch goquery to use your implementation then. Given &#39; is valid HTML escape and will render same as ' in browser I'd not recommend doing that.