Skip to main content

declxml - Declarative XML Processing

PyPI version Python Versions Build Status codecov Documentation Status License

XML processing made easy. No more writing and maintaining dozens or hundreds of lines of imperative serialization and parsing logic. With declxml, you declaratively define the structure of your XML document and let declxml handle the rest.

Installation

Install using either pip

pip install declxml

or Pipenv

pipenv install declxml

Documentation

For detailed documentation, see the project's documentation page.

Usage

Given some XML to process

<author>
    <name>Robert A. Heinlein</name>
    <birth-year>1907</birth-year>
    <book>
        <title>Starship Troopers</title>
        <published>1959</published>
    </book>
    <book>
        <title>Stranger in a Strange Land</title>
        <published>1961</published>
    </book>
</author>

Create a declxml processor that defines the structure of the document

>>> import declxml as xml

>>> author_processor = xml.dictionary('author', [
...     xml.string('name'),
...     xml.integer('birth-year'),
...     xml.array(xml.dictionary('book', [
...         xml.string('title'),
...         xml.integer('published')
...     ]), alias='books')
... ])

Then use that processor to parse the XML data

>>> from pprint import pprint
>>> author_xml = """
... <author>
...     <name>Robert A. Heinlein</name>
...     <birth-year>1907</birth-year>
...     <book>
...         <title>Starship Troopers</title>
...         <published>1959</published>
...     </book>
...     <book>
...         <title>Stranger in a Strange Land</title>
...         <published>1961</published>
...     </book>
... </author>
... """
>>> pprint(xml.parse_from_string(author_processor, author_xml))
{'birth-year': 1907,
     'books': [{'published': 1959, 'title': 'Starship Troopers'},
               {'published': 1961, 'title': 'Stranger in a Strange Land'}],
     'name': 'Robert A. Heinlein'}

The same processor can also be used to serialize data to XML

>>> author = {
...     'birth-year': 1920,
...     'name': 'Issac Asimov',
...     'books': [
...         {
...             'title': 'I, Robot',
...             'published': 1950
...         },
...         {
...             'title': 'Foundation',
...             'published': 1951
...         }
...     ]
...  }


>>> print(xml.serialize_to_string(author_processor, author, indent='    '))
<?xml version="1.0" encoding="utf-8"?>
<author>
    <name>Issac Asimov</name>
    <birth-year>1920</birth-year>
    <book>
        <title>I, Robot</title>
        <published>1950</published>
    </book>
    <book>
        <title>Foundation</title>
        <published>1951</published>
    </book>
</author>

Want to work with objects instead of dictionaries? You can do that with declxml too

>>> class Author:
...
...     def __init__(self):
...         self.name = None
...         self.birth_year = None
...         self.books = []
...
...     def __repr__(self):
...         return 'Author(name=\'{}\', birth_year={}, books={})'.format(
...             self.name, self.birth_year, self.books)

>>> class Book:
...
...     def __init__(self):
...         self.title = None
...         self.published = None
...
...     def __repr__(self):
...         return 'Book(title=\'{}\', published={})'.format(self.title, self.published)
...

>>> author_processor = xml.user_object('author', Author, [
...     xml.string('name'),
...     xml.integer('birth-year', alias='birth_year'),
...     xml.array(xml.user_object('book', Book, [
...         xml.string('title'),
...         xml.integer('published')
...     ]), alias='books')
... ])

>>> xml.parse_from_string(author_processor, author_xml)
Author(name='Robert A. Heinlein', birth_year=1907, books=[Book(title='Starship Troopers', published=1959), Book(title='Stranger in a Strange Land', published=1961)])

What about namedtuples, you say? Those are extremely useful, and declxml lets you work with them as well

>>> from collections import namedtuple


>>> Author = namedtuple('Author', ['name', 'birth_year', 'books'])
>>> Book = namedtuple('Book', ['title', 'published'])


>>> author_processor = xml.named_tuple('author', Author, [
...     xml.string('name'),
...     xml.integer('birth-year', alias='birth_year'),
...     xml.array(xml.named_tuple('book', Book, [
...         xml.string('title'),
...         xml.integer('published')
...     ]), alias='books')
... ])

>>> xml.parse_from_string(author_processor, author_xml)
Author(name='Robert A. Heinlein', birth_year=1907, books=[Book(title='Starship Troopers', published=1959), Book(title='Stranger in a Strange Land', published=1961)])

Metadata

Release files for declxml 1.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for declxml 1.1.3
File Size Uploaded
declxml-1.1.3.tar.gz 12.7 kB Details

Release files / declxml-1.1.3.tar.gz

Download URL declxml-1.1.3.tar.gz
Size 12.7 kB
Tags Source
SHA-256 checksum
How to use checksums
19b78c1ac9698cd836b18426aaa093ccb35cda4c7a0285021fe8ba6396063f20
BLAKE2b-256 checksum
How to use checksums
6c2a51d5fcd89783b06e40a4dba7ec1f4002eb6df21a6e5763610328c1efc10f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.12.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/39.0.1 requests-toolbelt/0.9.1 tqdm/4.30.0 CPython/3.7.0
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page