> For the complete documentation index, see [llms.txt](https://docs.datajet-app.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.datajet-app.com/liquid/filters/parse_xml_attrs.md).

# parse\_xml\_attrs

Parses an XML string into a Liquid object, **including element attributes**. Works exactly like `parse_xml` but keeps attributes instead of stripping them.

```liquid
{% assign data = xml_string | parse_xml_attrs %}
{% log data %}
```

#### Syntax

```liquid
{{ xml_string | parse_xml_attrs }}
```

| Parameter    | Description                        |
| ------------ | ---------------------------------- |
| `xml_string` | A string containing valid XML data |

#### Return Value

Returns a Liquid object representing the XML structure. Each attribute becomes a plain key on its element (e.g. `node.currency`). If an element has both attributes and text content, the text is available under the `#text` key.

#### Examples

**Read attributes from an API response:**

```liquid
{% assign xml = '<rate currency="USD" code="STD">9.99</rate>' %}
{% assign data = xml | parse_xml_attrs %}
{% log data.rate.currency %}     {# USD #}
{% log data.rate.code %}         {# STD #}
{% log data.rate['#text'] %}     {# 9.99 #}
```

**Iterate elements that carry attributes:**

```liquid
{% assign data = response.body | parse_xml_attrs %}
{% for line in data.order.line %}
  {% log line.sku | append: ": " | append: line['#text'] %}
{% endfor %}
```

#### Notes

* Attributes are exposed as plain keys, so they're dot-accessible like any element
* Text content of an element that also has attributes lives under `#text`
* If you don't need attributes, use `parse_xml` instead
* See also: `parse_xml`, `parse_json`, `parse_csv`
