# Data Formats `json/`, `yaml/`, and `xml/` convert between serialised text and Deft values. They are namespaced stdlib functions, compiled into every runtime and invoked with prefix calls (`[json/parse ...]`). All three readers return Deft maps with keyword keys plus strings, numbers, booleans, and `nil` — JSON arrays and XML repeated children come back as vectors; malformed input yields `%Err{:message}`. For the value side of the conversion, see Types and Maps. XML has more surface than the other two (document order, mixed content, entities, encodings) and has its own guide: XML. HTML — the tag-soup-tolerant format the web and mail actually use — is not well-formed parsing at all; it has its own guide too: HTML. ## Functions | Function | Purpose | |---|---| | `json/parse "text"` | Parse a JSON string into a Deft value | | `json/stringify $value` | Convert a value to a compact JSON string | | `json/pretty $value ?indent` | Convert a value to pretty-printed JSON; optional indent string (default two spaces) | | `yaml/parse "text"` | Parse a YAML string into a Deft value | | `yaml/load "path"` | Read a YAML file from disk and parse it into a Deft value | | `yaml/stringify $value ?indent` | Convert a value to a YAML string; optional indent string (default two spaces) | | `xml/parse "text" ?opts` | Parse an XML document into a Deft value (compact by default; `%{ :compact false }` or `:tree` for the tree shape) | | `xml/load "path" ?opts` | Read an XML file (UTF-8, UTF-16 with BOM, or ISO-8859-1 per the declaration) and parse it | | `xml/stringify $value` | Convert an XML value (compact or tree shape) to a compact XML element | | `xml/pretty $value ?indent` | Convert a value to indented XML; optional indent string (default two spaces) | | `xml/escape "text"` | Escape `& < > " '` as entity references | | `xml/unescape "text"` | Expand predefined and numeric character references | Notes: - The parse/load split is deliberate: `yaml/parse` takes the document text itself, while `yaml/load` takes a filesystem path and reads it for you (so it routes through the `fs/` layer and VFS mounts). There is no `json/load`; read the file with `fs/read`, `unwrap` the text, and pass it to `json/parse`. See Filesystem. - JSON objects and YAML mappings come back as Deft maps with keyword keys, so field access works directly: `$doc~name`. - The YAML reader is intentionally simple. Scalars and mappings parse cleanly, but block sequences currently come back as maps keyed by index (`%{ :0 x :1 y }`), and flow sequences (`[x, y]`) as raw strings. Prefer `json/parse` when arrays matter. - `json/pretty` and `yaml/stringify` accept an optional indent string; `yaml/stringify` appends a trailing newline. - XML has two shapes. The default compact shape uses the root element name as the key, attributes as `"@name"` keys, the element's own text as `"#text"`, and collapses leaf elements to their text. The tree shape (`[xml/parse $s %{ :compact false }]`) returns `%{ :name :attributes :children }` with children in document order. Attribute and text keys are read with string accessors: `[get $el "@id"]`, `[get $el "#text"]`. See XML for the full guide (entities, encodings, well-formedness, serialization). ## Examples ### Parse and access JSON
set doc [json/parse "{\"name\": \"ada\", \"age\": 36, \"admin\": true}"]
echo $doc~name            # ada
echo $doc~age             # 36

set text [json/stringify $doc]
echo $text                # {"admin":true,"age":36,"name":"ada"}
### Pretty-print
echo [json/pretty %{ :name "ada" :nested %{ :ok true } }]

# A custom indent string is the optional second argument
echo [json/pretty %{ :name "ada" } "--"]
### Read and write YAML
def path [fs/tmp-path "app.yaml"]
fs/write $path "name: ada\nport: 8080\n"

set cfg [yaml/load $path]
echo $cfg~name "listens on" $cfg~port

# The same mapping, from a string and back out as YAML
set inline [yaml/parse "name: ada\nport: 8080\n"]
echo [yaml/stringify $inline]
### Parse and access XML
set doc [xml/parse "<order id=\"A1\"><item sku=\"tea\">Green tea</item><paid/></order>"]
set order [get $doc "order"]

echo [get $order "@id"]                          # A1
echo [get [get $order "item"] "@sku"]            # tea
echo [get [get $order "item"] "#text"]           # Green tea
echo [get $order "paid"]                         # "" (empty element)
The XML page covers pretty-printing, the tree shape, and building documents from Deft data. ### Convert between formats
set from-yaml [yaml/parse "service: web\nport: 8080\n"]
set as-json   [json/stringify $from-yaml]
echo $as-json             # {"port":8080,"service":"web"}
## See Also - XML — the `xml/` namespace guide - Types — predicates, coercion, and type inspection - Maps — Deft maps and nested `~` access - Filesystem — `fs/read` / `fs/write` and VFS routing - Crypto — hashing and encoding of serialised payloads