Alexandre Stein
Alexandre Stein

Reputation: 21

golang template escape first char

I'm trying to build sitemap XML file with the standard template package.
But the first charset "<" become "&lt ;", and make the XML unreadable for clients.

package main

import (
    "bytes"
    "fmt"
    "html/template"
)

const (
    tmplStr = `{{define "indexSitemap"}}<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
    <loc>https://www.test.com/sitemap.xml</loc>
</sitemap>
<sitemap>
    <loc>https://www.test.com/events-sitemap.xml</loc>
</sitemap>
<sitemap>
    <loc>https://www.test.com/gamesAndTeams-sitemap.xml</loc>
</sitemap>
</sitemapindex>{{end}}`
)

func main() {
    // Parse the template and check for error
    tmpl, parseErr := template.New("test").Parse(tmplStr)
    if parseErr != nil {
        fmt.Println(parseErr)
        return
    }

    // Init the writer
    buf := new(bytes.Buffer)

    // Execute and get the template error if any
    tmplExErr := tmpl.ExecuteTemplate(buf, "indexSitemap", nil)
    if tmplExErr != nil {
        fmt.Println(tmplExErr)
        return
    }

    // Print the content malformed
    fmt.Println(buf)
}

playground golang

Is that normal?
How can I make it works normaly.

Thanks in advance

Upvotes: 1

Views: 1851

Answers (2)

Kenny Grant
Kenny Grant

Reputation: 9623

Also see issue #12496 on github which confirms they are not planning to fix this.

https://github.com/golang/go/issues/12496

Probably because this is the HTML templating package and you're trying to produce XML. I suspect that it doesn't know how to parse the directives with the question mark there.

You probably want to use the text/template package instead, if you're not going to be taking advantage of any of the HTML auto-escaping features.

Upvotes: 1

Not_a_Golfer
Not_a_Golfer

Reputation: 49195

Your example shows you're using the html/template package, which auto-escapes text for html usage.

If you want a raw template engine, use the text/template package instead - the html one just wraps it with context-aware escaping.

However, you'll need to make sure by yourself that the texts you output with the raw template engine are XML-safe. You can do this by exposing some escape function to your template, and passing all texts via this function instead of writing them directly.

[EDIT] It looks like a bug in html/template, if you omit the ? from the xml declaration it works okay. But still my advice stands - if it's not html you're better off using the text/template package. Actually, even better, describe the site map as a struct and don't use a template at all, just XML serialization.

Upvotes: 2

Related Questions