Metadata-Version: 2.4
Name: xmldataset
Version: 2.0.0
Summary: Extract Python datasets from XML using a simple, indented profile
Keywords: xml,parsing,dataset,extraction,etl
Author: James Spurin
Author-email: James Spurin <james@spurin.com>
License-Expression: BSD-3-Clause
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Markup :: XML
Classifier: Typing :: Typed
Requires-Dist: pyyaml>=6.0.2
Requires-Python: >=3.11
Project-URL: Homepage, https://github.com/spurin/xmldataset
Project-URL: Documentation, https://xmldataset.readthedocs.io
Project-URL: Changelog, https://github.com/spurin/xmldataset/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/spurin/xmldataset/issues
Description-Content-Type: text/markdown

# xmldataset: simple XML parsing 🗃️

[![CI](https://github.com/spurin/xmldataset/actions/workflows/ci.yml/badge.svg)](https://github.com/spurin/xmldataset/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/xmldataset)](https://pypi.org/project/xmldataset/)
[![Python versions](https://img.shields.io/pypi/pyversions/xmldataset)](https://pypi.org/project/xmldataset/)
[![Documentation](https://readthedocs.org/projects/xmldataset/badge/?version=latest)](https://xmldataset.readthedocs.io)

![xmldataset logo](https://xmldataset.readthedocs.io/en/latest/_static/logo.jpg)

**Extract Python datasets from XML with a simple profile that mirrors the XML.**

A *profile* lists the elements and attributes you want, indented the same way as
the XML, and names the *dataset* each value belongs to. xmldataset returns every
dataset as a list of records (plain dicts), ready for JSON, CSV, pandas or a
database.

**Profiles can be written as indented text, YAML or JSON.** All three are
equivalent, and you can convert between them at any time.

- Documentation: <https://xmldataset.readthedocs.io>

## Installation

```console
pip install xmldataset
```

xmldataset requires Python 3.11 or newer. Its only dependency is
[PyYAML](https://pypi.org/project/PyYAML/), for YAML profiles.

## Example

Given this XML:

```xml
<colleagues>
    <colleague>
        <title>The Boss</title>
        <email>boss@example.com</email>
    </colleague>
    <colleague>
        <title>Minion</title>
    </colleague>
</colleagues>
```

this profile collects every colleague into a dataset called `colleagues`:

```text
colleagues
    colleague
        title = dataset:colleagues
        email = dataset:colleagues,default:none
```

<details>
<summary>The same profile in YAML</summary>

```yaml
colleagues:
  colleague:
    title: colleagues
    email:
      $dataset: colleagues
      $default: none
```

</details>

<details>
<summary>The same profile in JSON</summary>

```json
{
  "colleagues": {
    "colleague": {
      "title": "colleagues",
      "email": {
        "$dataset": "colleagues",
        "$default": "none"
      }
    }
  }
}
```

</details>

```python
import xmldataset

result = xmldataset.parse_using_profile(xml, profile)
```

```json
{
  "colleagues": [
    {"title": "The Boss", "email": "boss@example.com"},
    {"title": "Minion", "email": "none"}
  ]
}
```

The Minion has no email address, so the default fills it in.

Load a profile file in any format with `xmldataset.load_profile("profile.yaml")`,
or stream records from a large file in flat memory:

```python
from pathlib import Path

for dataset, record in xmldataset.iter_records(Path("huge.xml"), profile):
    ...
```

Or skip Python entirely:

```console
xmldataset run profile.yaml data.xml --format csv --dataset colleagues
xmldataset convert profile.txt --to yaml
```

## Features

- **Three profile formats**: indented text, YAML or JSON, with a JSON Schema for
  editor completion and validation.
- **Elements and attributes**, with renaming, prefixes, defaults, lists of
  repeated values and per-value process functions.
- **Correct records by construction**: a record never mixes values from two
  elements, and values from an enclosing element (a shop's number, say) are
  copied into every record inside it.
- **Streams documents of any size** in flat memory from a string, bytes, a path
  or a file, and hands over each record as soon as it is complete.
- **Namespaces**, matched by local name or by prefix.
- **A command-line tool** to run, convert and validate profiles.
- **Typed**, with PyYAML as the only dependency.

## Contributing

See [CONTRIBUTING.md](https://github.com/spurin/xmldataset/blob/main/CONTRIBUTING.md).
Changes are recorded in
[CHANGELOG.md](https://github.com/spurin/xmldataset/blob/main/CHANGELOG.md).

## License

BSD-3-Clause. See [LICENSE](https://github.com/spurin/xmldataset/blob/main/LICENSE).
