--- title: transform.Unmarshal description: Parses serialized data and returns a map or an array. Supports CSV, JSON, TOML, YAML, and XML. categories: [] keywords: [] params: functions_and_methods: aliases: [unmarshal] returnType: any signatures: ['transform.Unmarshal [OPTIONS] INPUT'] aliases: [/functions/transform.unmarshal] --- The input can be a string or a [resource](g). ## Options The `transform.Unmarshal` function accepts an options map. `delimiter` : (`string`) Applicable to CSV files. The delimiter used. Default is `,`. `comment` : (`string`) Applicable to CSV files. The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored. `format` : {{< new-in 0.149.0 />}} : (`string`) The serialization format of the input, one of `csv`, `json`, `org`, `toml`, `xml`, or `yaml`. If empty or unspecified, Hugo infers the format from the input. For resources, this option is only needed if the file lacks an extension or to override the inferred format. For strings, it's only required when the format is ambiguous. `lazyQuotes` : (`bool`) Applicable to CSV files. Whether to allow a quote in an unquoted field, or to allow a non-doubled quote in a quoted field. Default is `false`. `targetType` : {{< new-in 0.146.7 />}} : (`string`) Applicable to CSV files. The target data type, either `slice` or `map`. Default is `slice`. ## Unmarshal a string ```go-html-template {{ $string := ` title: Les Misérables author: Victor Hugo `}} {{ $book := transform.Unmarshal $string }} {{ $book.title }} → Les Misérables {{ $book.author }} → Victor Hugo ``` ## Unmarshal a resource Use the `transform.Unmarshal` function with global, page, and remote resources. ### Global resource A global resource is a file within the `assets` directory, or within any directory mounted to the `assets` directory. ```tree assets/ └── data/ └── books.json ``` ```go-html-template {{ $data := dict }} {{ $path := "data/books.json" }} {{ with resources.Get $path }} {{ with . | transform.Unmarshal }} {{ $data = . }} {{ end }} {{ else }} {{ errorf "Unable to get global resource %q" $path }} {{ end }} {{ range where $data "author" "Victor Hugo" }} {{ .title }} → Les Misérables {{ end }} ``` ### Page resource A page resource is a file within a [page bundle][]. ```tree content/ ├── post/ │ └── book-reviews/ │ ├── books.json │ └── index.md └── _index.md ``` ```go-html-template {{ $data := dict }} {{ $path := "books.json" }} {{ with .Resources.Get $path }} {{ with . | transform.Unmarshal }} {{ $data = . }} {{ end }} {{ else }} {{ errorf "Unable to get page resource %q" $path }} {{ end }} {{ range where $data "author" "Victor Hugo" }} {{ .title }} → Les Misérables {{ end }} ``` ### Remote resource A remote resource is a file on a remote server, accessible via HTTP or HTTPS. ```go-html-template {{ $data := dict }} {{ $url := "https://example.org/books.json" }} {{ with try (resources.GetRemote $url) }} {{ with .Err }} {{ errorf "%s" . }} {{ else with .Value }} {{ $data = . | transform.Unmarshal }} {{ else }} {{ errorf "Unable to get remote resource %q" $url }} {{ end }} {{ end }} {{ range where $data "author" "Victor Hugo" }} {{ .title }} → Les Misérables {{ end }} ``` > [!NOTE] > When retrieving remote data, a misconfigured server may send a response header with an incorrect [Content-Type][]. For example, the server may set the Content-Type header to `application/octet-stream` instead of `application/json`. > > In these cases, pass the resource `Content` through the `transform.Unmarshal` function instead of passing the resource itself. For example, in the above, do this instead: > > `{{ $data = .Content | transform.Unmarshal }}` ## Working with CSV The examples below use this CSV file: ```csv "name","type","breed","age" "Spot","dog","Collie",3 "Rover","dog","Boxer",5 "Felix","cat","Calico",7 ``` To render an HTML table from a CSV file: ```go-html-template {{ $data := slice }} {{ $file := "pets.csv" }} {{ with or (.Resources.Get $file) (resources.Get $file) }} {{ $opts := dict "targetType" "slice" }} {{ $data = transform.Unmarshal $opts . }} {{ end }} {{ with $data }} {{ range index . 0 }} {{ end }} {{ range . | after 1 }} {{ range . }} {{ end }} {{ end }}
{{ . }}
{{ . }}
{{ end }} ``` To extract a subset of the data, or to sort the data, unmarshal to a map instead of a slice: ```go-html-template {{ $data := dict }} {{ $file := "pets.csv" }} {{ with or (.Resources.Get $file) (resources.Get $file) }} {{ $opts := dict "targetType" "map" }} {{ $data = transform.Unmarshal $opts . }} {{ end }} {{ with sort (where $data "type" "dog") "name" "asc" }} {{ range . }} {{ end }}
name type breed age
{{ .name }} {{ .type }} {{ .breed }} {{ .age }}
{{ end }} ``` ## Working with XML When unmarshaling an XML file, do not include the root node when accessing data. For example, after unmarshaling the RSS feed below, access the feed title with `$data.channel.title`. ```xml Books on Example Site https://example.org/books/ Recent content in Books on Example Site en-US The Hunchback of Notre Dame Written by Victor Hugo https://example.org/books/the-hunchback-of-notre-dame/ Mon, 09 Oct 2023 09:27:12 -0700 https://example.org/books/the-hunchback-of-notre-dame/ Les Misérables Written by Victor Hugo https://example.org/books/les-miserables/ Mon, 09 Oct 2023 09:27:11 -0700 https://example.org/books/les-miserables/ ``` Get the remote data: ```go-html-template {{ $data := dict }} {{ $url := "https://example.org/books/index.xml" }} {{ with try (resources.GetRemote $url) }} {{ with .Err }} {{ errorf "%s" . }} {{ else with .Value }} {{ $data = . | transform.Unmarshal }} {{ else }} {{ errorf "Unable to get remote resource %q" $url }} {{ end }} {{ end }} ``` Inspect the data structure: ```go-html-template
{{ debug.Dump $data }}
``` List the book titles: ```go-html-template {{ with $data.channel.item }} {{ end }} ``` Hugo renders this to: ```html ``` ### XML attributes and namespaces Let's add a `lang` attribute to the `title` nodes of our RSS feed, and a namespaced node for the ISBN number: ```xml Books on Example Site https://example.org/books/ Recent content in Books on Example Site en-US The Hunchback of Notre Dame Written by Victor Hugo 9780140443530 https://example.org/books/the-hunchback-of-notre-dame/ Mon, 09 Oct 2023 09:27:12 -0700 https://example.org/books/the-hunchback-of-notre-dame/ Les Misérables Written by Victor Hugo 9780451419439 https://example.org/books/les-miserables/ Mon, 09 Oct 2023 09:27:11 -0700 https://example.org/books/les-miserables/ ``` After retrieving the remote data, inspect the data structure: ```go-html-template
{{ debug.Dump $data }}
``` Each item node looks like this: ```json { "description": "Written by Victor Hugo", "guid": "https://example.org/books/the-hunchback-of-notre-dame/", "link": "https://example.org/books/the-hunchback-of-notre-dame/", "number": "9780140443530", "pubDate": "Mon, 09 Oct 2023 09:27:12 -0700", "title": { "#text": "The Hunchback of Notre Dame", "-lang": "en" } } ``` The title keys do not begin with an underscore or a letter---they are not valid [identifiers](g). Use the [`index`][] function to access the values: ```go-html-template {{ with $data.channel.item }} {{ end }} ``` Hugo renders this to: ```html ``` [Content-Type]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type [`index`]: /functions/collections/indexfunction/ [page bundle]: /content-management/page-bundles/