---
title: XML
description: Convert between XML and JSON
---

Turn an XML document (a feed, an API answer, a sitemap) into fields you can use, or build XML from your data.

## What it does

The XML node converts in one of two directions, set by **Direction**:

* **XML to JSON** reads XML text and turns its elements and attributes into fields. The result is keyed by the root element, so `<rss>…</rss>` becomes `{ "rss": { … } }`.
* **JSON to XML** takes an object and writes it out as XML text.

Both directions use the same simple rules:

* **Attributes** get an `@` in front: `<a href="x"/>` becomes `{ "a": { "@href": "x" } }`.
* **An element with only text** becomes that text: `<a>hello</a>` becomes `{ "a": "hello" }`.
* **Text next to attributes or child elements** goes under `#text`: `<a href="x">hi</a>` becomes `{ "a": { "@href": "x", "#text": "hi" } }`.
* **Repeated elements** with the same name become a list: two `<item>` elements become `"item": ["1", "2"]`. A single `<item>` stays a single value, not a list of one.
* **An empty element** becomes empty text: `<a/>` becomes `{ "a": "" }`.

For safety, XML that declares its own entities (`<!ENTITY …>`) or points to an outside definition file (`<!DOCTYPE … SYSTEM …>` or `PUBLIC`) is refused. The text can be up to about 2 MB.

## When to use it

* Read an RSS or Atom feed, a sitemap, or an API that answers in XML.
* Pull values out of an XML file you loaded with [Extract From File](/nodes/builtin/datatransformation/extractfromfile/) or [Local File Read](/nodes/builtin/datatransformation/localfileread/).
* Build an XML body for a service that only accepts XML, then send it with [Http Request](/nodes/builtin/core/http-request/).
* For web pages, use [HTML Extract](/nodes/builtin/datatransformation/html-extract/) instead: HTML is rarely valid XML.

## Inputs and settings

* **Where the input comes from.** **Input** wins if it is filled, for example `{{ $input.data }}`. Otherwise the node reads **Source Field** (dots reach nested fields). If both are empty, it uses the incoming item itself. Only the first incoming item is read.
* **For JSON to XML**, the object needs exactly one top-level key, which becomes the root element: `{ "order": { "@id": "42", "item": ["A", "B"] } }` gives `<order id="42"><item>A</item><item>B</item></order>`. **Input** also accepts JSON text.
* **Put Result In Field** is only used by JSON to XML. XML to JSON always outputs the converted object as the item.

## Outputs

* **XML to JSON**: one item keyed by the root element. Read nested values with dots, for example `{{ $input.rss.channel.title }}`. Repeated elements are lists, so split them with [Split Out](/nodes/builtin/datatransformation/splitout/) on a path such as `rss.channel.item`.
* **JSON to XML**: one item with the XML text in **Put Result In Field** (`data` by default).

Values read from XML are always text. For example, set **Compare As** to *Number* in [Sort](/nodes/builtin/datatransformation/sort/) when you sort by a price read from XML.

## Dependencies and credentials

None. This node needs no connection and has no slots for other nodes.

## Example workflow

1. An [Http Request](/nodes/builtin/core/http-request/) node fetches a blog's RSS feed. The XML text arrives in its `data` field.
2. XML with **Direction** *XML to JSON* and **Source Field** `data`.
3. [Split Out](/nodes/builtin/datatransformation/splitout/) with **Field To Split Out** `rss.channel.item` and **Output field name** `post` gives one item per article.
4. [Limit](/nodes/builtin/datatransformation/limit/) with **Max Items** `3` keeps the first three, and a [Slack](/nodes/builtin/integration/slack/) node posts `{{ $input.post.title }}` and `{{ $input.post.link }}`.

## Common issues

* **"This is not valid XML: …".** The text is not well-formed XML, often because it is an HTML page or an error message. Look at what the previous node returned.
* **"XML to JSON needs XML text. This input is already parsed data."** The node got an object instead of text. Set **Source Field** to the field that holds the XML, such as `data`.
* **"This XML declares a DTD with internal entities or an external subset …"** The document starts with a `<!DOCTYPE …>` block that defines entities or loads an outside file. This is refused on purpose. Remove that block before converting, for example with [Regex](/nodes/builtin/datatransformation/regex/) *Replace*.
* **"JSON to XML needs an object with exactly one root element key; found …".** Wrap your data in one key, for example `{ "order": { … } }`.
* **"An array cannot be an element value directly; nest it under a key."** A list sits directly where an element should be. Put it under a named key, and each entry becomes a repeated element with that name.

## Related nodes

* [JSON](/nodes/builtin/datatransformation/json/): parse, build and reshape JSON text.
* [HTML Extract](/nodes/builtin/datatransformation/html-extract/): read values from web pages.
* [Split Out](/nodes/builtin/datatransformation/splitout/): turn repeated elements into separate items.