Skip to content

Infumia/xml_object_mapping

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

xml_object_mapping

Pub Version

A Dart library for mapping XML data to Dart objects using annotations. Inspired by JSON serialization patterns, this package eliminates boilerplate XML parsing code.

Features

  • Declarative annotations for XML elements and attributes
  • Automatic type conversion and validation
  • Support for nested objects and collections
  • Custom type converters
  • Null safety support

Getting Started

Installation

Add to your pubspec.yaml:

dependencies:
  xml: ^6.0.0
  xml_object_mapping: ^1.0.0

dev_dependencies:
  xml_object_mapping_generator: ^1.0.0

Basic Usage

Define your model class with annotations:

<user id="123">
    <nameSurname>...</nameSurname>
    <email>...</email>
    <maxItems>9</maxItems>
    <status>PROCESSING</status>
</user>
import "package:xml_object_mapping/xml_object_mapping.dart";

part "user.g.dart";

@xmlMap
class User {
  @xmlMapAttribute
  final int id;

  @XmlMapElement(overrideName: "nameSurname")
  final String name;

  @xmlMapElement
  final String email;

  @xmlMapElement
  final String? phone;

  @xmlMapElement
  final int maxItems;

  @xmlMapElement
  final OrderStatus status;

  User({
    required this.id,
    required this.name,
    required this.email,
    required this.status,
    this.phone,
    this.maxItems = 10,
  });
}

enum OrderStatus { PENDING, PROCESSING, SHIPPED, DELIVERED }

Run the build runner to generate the mapper:

dart run build_runner build

This generates UserXmlMapper. Use it to parse XML from various sources:

void main() {
    var user = UserXmlMapper.parse(path: 'data/user.xml');
    user = UserXmlMapper.parse(file: File('data/user.xml'));
    user = UserXmlMapper.parse(text: "<user>...<user/>");
    user = UserXmlMapper.parse(xmlElement: xmlElement);
}

Annotations

Annotation Description
@XmlMap Marks a class for XML mapping code generation
@XmlMapValue({XmlConverter? converter}) Maps the content of an XML element to a field
@XmlMapElement({String? overrideName, XmlConverter? converter}) Maps an XML element to a field
@XmlMapAttribute({String? overrideName, XmlConverter? converter}) Maps an XML attribute to a field
@XmlMapList({String? overrideName, String? childName, XmlConverter? converter}) Maps repeated elements to a List field

Supported Types

The following built-in types are supported out of the box:

Type Description
String Text content
int Integer numbers
double Floating-point numbers
num Any numeric type
bool Boolean values (true/false)
DateTime ISO 8601 date-time strings

For other types, use custom converters (see below).

Advanced Usage

Nested Objects

<company>
    <name>...</name>
    <address>
        <street>...</street>
        <city>...</city>
    </address>
</company>
@xmlMap
class Company {
  @xmlMapElement
  final String name;

  @xmlMapElement
  final Address address;

  Company({required this.name, required this.address});
}

@xmlMap
class Address {
  @xmlMapElement
  final String street;

  @xmlMapElement
  final String city;

  Address({required this.street, required this.city});
}

Collections

<library>
    <books>
        <bookName>...</bookName>
        <bookName>...</bookName>
    </books>
</library>
@xmlMap
class Library {
  @XmlMapList(childName: 'bookName')
  final List<String> books;

  Library({required this.books});
}

Collections of Nested Objects

<bookstore>
    <books>
        <book>
            <title>...</title>
            <author>...</author>
            <price>...</price>
        </book>
        <book>
            <title>...</title>
            <author>...</author>
            <price>...</price>
        </book>
    </books>
</bookstore>
@xmlMap
class Bookstore {
  @XmlMapList(childName: 'book')
  final List<Book> books;

  Bookstore({required this.books});
}

@xmlMap
class Book {
  @xmlMapElement
  final String title;

  @xmlMapElement
  final String author;

  @xmlMapElement
  final double price;

  Book({required this.title, required this.author, required this.price});
}

Custom Converters

<product>
    <price>$19.99</price>
</product>
@xmlMap
class Product {
  @XmlMapElement(converter: PriceConverter())
  final double price;

  Product({required this.price});
}

class PriceConverter implements XmlConverter<double> {
  const PriceConverter();

  @override
  double convert(String value) => double.parse(value.replaceAll(r"$", ""));
}

Map Types

Use @XmlMapList with a map-like structure for key-value pairs:

<config>
    <properties>
        <entry key="timeout">30</entry>
        <entry key="retries">3</entry>
    </properties>
</config>
@xmlMap
class Config {
  @XmlMapList(childName: 'entry')
  final List<PropertyEntry> properties;

  Config({required this.properties});
}

@xmlMap
class PropertyEntry {
  @xmlMapAttribute
  final String key;

  @xmlMapValue
  final int value;

  PropertyEntry({required this.key, required this.value});
}

void main() {
    final config = XmlConfigMapper.parse(text: xml);
    final map = {for (var e in config.properties) e.key: e.value};
}

Serialization (Objects → XML)

Convert objects back to XML:

void main() {
    final user = User(id: '123', name: 'John Doe', email: '[email protected]');

    final xmlElement = UserXmlMapper.toXml(user);
}

Error Handling

The mapper throws specific exceptions for common errors:

void main() {
    try {
        final user = UserXmlMapper.parse(text: xmlString);
    } on XmlMappingException catch (e) {
        print('Mapping error: ${e.message}');
    } on XmlFormatException catch (e) {
        print('Format error: ${e.message}');
    } on XmlParserException catch (e) {
        print('Parse error: ${e.message}');
    }
}

About

A Dart library that simplifies converting XML data into strongly-typed Dart objects.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages