> For the complete documentation index, see [llms.txt](https://docs.couchdrop.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.couchdrop.io/automations/actions/transform-files.md).

# Transform Files

Learn how to transform files with Couchdrop Automations

## Overview

Transform actions let you read data from a file into Automation Variables or create a new file using data already available within a workflow. This makes them useful for lightweight ETL and EDI-style workflows, where structured data needs to be parsed, evaluated, and written into a new file format or structure.

For example, you can parse rows from a CSV file into a variable, use those values in later actions, and then write selected Automation Variables into a new file.

### Available Transform Actions

<table><thead><tr><th width="241.58203125">Action</th><th>Description</th></tr></thead><tbody><tr><td>Parse File</td><td>Parse a CSV or XML file into an Automation Variable that can be used by later workflow actions.</td></tr><tr><td>Write to File</td><td>Create a new CSV, XML, or text-based file using Automation Variables and optional <a href="#jinja-examples">Jinja</a> logic.</td></tr></tbody></table>

### Variables

Both transform actions can work with [Automation Variables](/automations/variables.md).

**Parse File** creates a new variable from the contents of a CSV or XML file. **Write to File** consumes variables and writes their values into a newly created file.

Standard workflow variables are available, [custom variables](/automations/variables.md#custom-variables) created by other workflow actions can also become available where supported.

{% hint style="info" %}
When using **Parse File**, place the action before any action that needs the parsed variable. Actions earlier in the workflow cannot access variables that have not yet been created.
{% endhint %}

## Parse File

The **Parse File** action reads the contents of a file and stores the parsed data as an Automation Variable.

Configure this action as early as possible in your workflow. The variable created by **Parse File** is only available to actions that run after it. If the Parse File action fails, subsequent actions will not execute.

{% hint style="info" %}
The maximum file size for parsing is **10 MB**. CSV files are limited to **50,000 rows**.
{% endhint %}

### Parsing CSV files

Select **CSV** as the file type to parse a CSV file.

Configure:

* **Variable name** — Enter a unique name for the Automation Variable. The parsed CSV is stored as an Automation Variable list.
* **Column delimiter** — Enter the character used to separate values within the CSV.
* **File Has Headers** — Enable this if the first row of the CSV contains column names.
* **Column headers** — If the CSV does not contain headers, you can define them manually using **Add CSV Column Headers** and **Add Header**.

If no column headers are supplied, Couchdrop generates default field names such as `column_0`.

The resulting variable is a list, so you can optionally use a **Loop** node to run actions for each item within that list.

### Parsing XML files

Select **XML** as the file type to parse an XML file.

Enter a unique **Variable name** for the parsed content. Couchdrop stores the resulting value as an Automation Variable JSON object that can be referenced by later actions.

### Using parsed variables

Once the file has been parsed, later actions can access its data through **Add Automation Variable**.

For CSV files, the variable contains a list of parsed rows. For XML files, the variable contains a JSON object representing the parsed file.

## Write to File

The **Write to File** action creates a new file using values available within the workflow.

The destination file must not already exist.

Configure:

* **File path** — Select the location and filename Couchdrop should create.
* **File type** — Select **CSV**, **XML**, or **Other**.
* **File content** — Define the content that Couchdrop should write to the file.

You can use **Add Automation Variable** to insert values from the workflow and **Add Jinja Block** when the output requires looping or other templating logic.

### Writing CSV files

Select **CSV**, then enter the output in CSV format.

Automation Variables can be inserted into the CSV content, allowing values generated earlier in the workflow to be written into the new file.

For more complex output, use Jinja to work with lists or other structured Automation Variables.

### Writing XML files

Select **XML**, then enter the XML structure that should be written to the new file.

For example, a Jinja loop can generate repeated XML elements from an Automation Variable list:

```xml
<WrapperTag>
    {% for item in {CUSTOM.Variable.ListField} %}
    <ItemTag>{{ item.Field }}</ItemTag>
    {% endfor %}
</WrapperTag>
```

In this example, Couchdrop loops through the values in the supplied Automation Variable and writes an `<ItemTag>` for each item.

### Writing JSON and other file types

Select **Other** to create a text-based file without using the CSV or XML-specific editors.

Enter the required text and optionally include Automation Variables or Jinja blocks to generate the content dynamically.

## Jinja Blocks

{% hint style="info" %}
Jinja is a templating language that lets you dynamically generate file content using variables, loops, and conditional logic.

In Couchdrop, you can use Jinja in Write to File actions to work with Automation Variables and build structured CSV, XML, or text output.

For more information about Jinja syntax and templating concepts, see the [official Jinja documentation](https://jinja.palletsprojects.com/).
{% endhint %}

Jinja blocks can be used in **Write to File** actions to control how Automation Variables are written into a new file.

Select **Add Jinja Block** to choose from the available block types.

#### Available Jinja Blocks

| Block                | Description                                                                            |
| -------------------- | -------------------------------------------------------------------------------------- |
| Jinja Variable Block | Insert an Automation Variable into the file content.                                   |
| Loop Block           | Loop through a list, writing content for each item in the list.                        |
| If Block             | Write content if a condition evaluates to `True`.                                      |
| If-Else Block        | Write content if a condition evaluates to `True`; otherwise write alternative content. |
| If-Elif-Else Block   | Write content based on multiple conditions.                                            |

### Loop Block

Use a **Loop Block** when an Automation Variable contains a list and you want to write content for each item.

For example:

```jinja
{% for item in {CUSTOM.Customers} %}
{{ item.Name }},{{ item.Email }}
{% endfor %}
```

If `{CUSTOM.Customers}` contains multiple items, Couchdrop writes one line for each item in the list.

A loop can also be used to generate repeated XML elements:

```xml
<Customers>
{% for item in {CUSTOM.Customers} %}
    <Customer>
        <Name>{{ item.Name }}</Name>
        <Email>{{ item.Email }}</Email>
    </Customer>
{% endfor %}
</Customers>
```

### If Block

Use an **If Block** when content should only be written when a condition evaluates to `True`.

For example:

```jinja
{% if item.Status == "Active" %}
{{ item.Name }},{{ item.Email }}
{% endif %}
```

In this example, the content is only written when the value of `Status` is `Active`.

### If-Else Block

Use an **If-Else Block** when you want one value written when a condition is true and an alternative value when it is false.

For example:

```jinja
{% if item.Status == "Active" %}
Active
{% else %}
Inactive
{% endif %}
```

### If-Elif-Else Block

Use an **If-Elif-Else Block** when the output depends on several possible conditions.

For example:

```jinja
{% if item.Status == "Active" %}
Active
{% elif item.Status == "Pending" %}
Pending
{% else %}
Inactive
{% endif %}
```

Couchdrop evaluates each condition in order and writes the content associated with the first matching condition. If none of the preceding conditions match, the content in the `else` block is written.

### Combining Loops and Conditions

Jinja blocks can be used together when generating content from a list.

For example, you can loop through parsed CSV rows and only write rows matching a condition:

```jinja
Name,Email
{% for item in {CUSTOM.Customers} %}
{% if item.Status == "Active" %}
{{ item.Name }},{{ item.Email }}
{% endif %}
{% endfor %}
```

This example loops through the `{CUSTOM.Customers}` list and writes a CSV row only when the item's `Status` value is `Active`.

{% hint style="info" %}
The fields available within a Jinja block depend on the Automation Variable being used. When working with a CSV parsed using **Parse File**, field names correspond to the CSV headers configured or detected during parsing.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.couchdrop.io/automations/actions/transform-files.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
