xml_serializable 2.5.4 copy "xml_serializable: ^2.5.4" to clipboard
xml_serializable: ^2.5.4 copied to clipboard

Automatically generate code for converting to and from XML by annotating Dart classes.

XML Serializable #

Pub Version

Provides build builders for handling XML.

The builders generate code when they find members annotated with classes defined in xml_annotation.

Getting Started #

  1. Define the XML document that you would like to serialize.
    <?xml version="1.0"?>
    <bookshelf>
      <book>
        <title lang="English">XML Pocket Reference</title>
        <author>Simon St. Laurent</author>
        <author>Michael James Fitzgerald</author>
        <price></price>
      </book>
      <book>
        <title lang="English">HTML and XHTML Pocket Reference</title>
        <author>Jennifer Niederst Robbins</author>
        <price></price>
      </book>
    </bookshelf>
    
  2. Add the necessary classes to model the XML document.
    class Book {
      Title? title;
    
      List<String>? authors;
    
      String? price;
    
      Book({
        this.title,
        this.authors,
        this.price,
      });
    }
    
    class Bookshelf {
      List<Book>? books;
    
      String? price;
    
      Bookshelf({
        this.books,
        this.price,
      });
    }
    
    enum Language {
      mandarin,
      spanish,
      english,
      hindi,
      bengali,
    }
    
    class Title {
      Language? language;
    
      String? text;
    
      Title({
        this.language,
        this.text,
      });
    }
    
  3. Annotate the classes and properties with XML annotations.
    @annotation.XmlRootElement(name: 'book')
    @annotation.XmlSerializable()
    class Book {
      @annotation.XmlElement(name: 'title')
      Title? title;
    
      @annotation.XmlElement(name: 'author')
      List<String>? authors;
    
      @annotation.XmlElement(name: 'price', isSelfClosing: false)
      String? price;
    
      Book({
        this.title,
        this.authors,
        this.price,
      });
    }
    
    @annotation.XmlRootElement(name: 'bookshelf')
    @annotation.XmlSerializable()
    class Bookshelf {
      @annotation.XmlElement(name: 'book')
      List<Book>? books;
    
      @annotation.XmlElement(name: 'price', includeIfNull: false)
      String? price;
    
      Bookshelf({
        this.books,
        this.price,
      });
    }
    
    @annotation.XmlEnum(fieldRename: annotation.FieldRename.pascal)
    enum Language {
      mandarin,
      spanish,
      english,
      hindi,
      bengali,
    }
    
    @annotation.XmlRootElement(name: 'title')
    @annotation.XmlSerializable()
    class Title {
      @annotation.XmlAttribute(name: 'lang')
      Language? language;
    
      @annotation.XmlText()
      String? text;
    
      Title({
        this.language,
        this.text,
      });
    }
    
  4. Add the required serialization helper methods to the classes.
    @annotation.XmlRootElement(name: 'book')
    @annotation.XmlSerializable()
    class Book {
      @annotation.XmlElement(name: 'title')
      Title? title;
    
      @annotation.XmlElement(name: 'author')
      List<String>? authors;
    
      @annotation.XmlElement(name: 'price', isSelfClosing: false)
      String? price;
    
      Book({
        this.title,
        this.authors,
        this.price,
      });
    
      factory Book.fromXmlElement(XmlElement element) =>
          _$BookFromXmlElement(element);
    
      @override
      String toString() {
        return 'Book{title: $title, authors: $authors, price: $price}';
      }
    
      void buildXmlChildren(
        XmlBuilder builder, {
        Map<String, String> namespaces = const {},
      }) =>
          _$BookBuildXmlChildren(
            this,
            builder,
            namespaces: namespaces,
          );
    
      void buildXmlElement(
        XmlBuilder builder, {
        Map<String, String> namespaces = const {},
      }) =>
          _$BookBuildXmlElement(
            this,
            builder,
            namespaces: namespaces,
          );
    
      List<XmlAttribute> toXmlAttributes({
        Map<String, String?> namespaces = const {},
      }) =>
          _$BookToXmlAttributes(
            this,
            namespaces: namespaces,
          );
    
      List<XmlNode> toXmlChildren({
        Map<String, String?> namespaces = const {},
      }) =>
          _$BookToXmlChildren(
            this,
            namespaces: namespaces,
          );
    
      XmlElement toXmlElement({
        Map<String, String?> namespaces = const {},
      }) =>
          _$BookToXmlElement(
            this,
            namespaces: namespaces,
          );
    }
    
    @annotation.XmlRootElement(name: 'bookshelf')
    @annotation.XmlSerializable()
    class Bookshelf {
      @annotation.XmlElement(name: 'book')
      List<Book>? books;
    
      @annotation.XmlElement(name: 'price', includeIfNull: false)
      String? price;
    
      Bookshelf({
        this.books,
        this.price,
      });
    
      factory Bookshelf.fromXmlElement(XmlElement element) =>
          _$BookshelfFromXmlElement(element);
    
      @override
      String toString() {
        return 'Bookshelf{books: $books, price: $price}';
      }
    
      void buildXmlChildren(
        XmlBuilder builder, {
        Map<String, String> namespaces = const {},
      }) =>
          _$BookshelfBuildXmlChildren(
            this,
            builder,
            namespaces: namespaces,
          );
    
      void buildXmlElement(
        XmlBuilder builder, {
        Map<String, String> namespaces = const {},
      }) =>
          _$BookshelfBuildXmlElement(
            this,
            builder,
            namespaces: namespaces,
          );
    
      List<XmlAttribute> toXmlAttributes({
        Map<String, String?> namespaces = const {},
      }) =>
          _$BookshelfToXmlAttributes(
            this,
            namespaces: namespaces,
          );
    
      List<XmlNode> toXmlChildren({
        Map<String, String?> namespaces = const {},
      }) =>
          _$BookshelfToXmlChildren(
            this,
            namespaces: namespaces,
          );
    
      XmlElement toXmlElement({
        Map<String, String?> namespaces = const {},
      }) =>
          _$BookshelfToXmlElement(
            this,
            namespaces: namespaces,
          );
    }
    
    @annotation.XmlEnum(fieldRename: annotation.FieldRename.pascal)
    enum Language {
      mandarin,
      spanish,
      english,
      hindi,
      bengali,
    }
    
    @annotation.XmlRootElement(name: 'title')
    @annotation.XmlSerializable()
    class Title {
      @annotation.XmlAttribute(name: 'lang')
      Language? language;
    
      @annotation.XmlText()
      String? text;
    
      Title({
        this.language,
        this.text,
      });
    
      factory Title.fromXmlElement(XmlElement element) =>
          _$TitleFromXmlElement(element);
    
      @override
      String toString() {
        return 'Title{language: $language, text: $text}';
      }
    
      void buildXmlChildren(
        XmlBuilder builder, {
        Map<String, String> namespaces = const {},
      }) =>
          _$TitleBuildXmlChildren(
            this,
            builder,
            namespaces: namespaces,
          );
    
      void buildXmlElement(
        XmlBuilder builder, {
        Map<String, String> namespaces = const {},
      }) =>
          _$TitleBuildXmlElement(
            this,
            builder,
            namespaces: namespaces,
          );
    
      List<XmlAttribute> toXmlAttributes({
        Map<String, String?> namespaces = const {},
      }) =>
          _$TitleToXmlAttributes(
            this,
            namespaces: namespaces,
          );
    
      List<XmlNode> toXmlChildren({
        Map<String, String?> namespaces = const {},
      }) =>
          _$TitleToXmlChildren(
            this,
            namespaces: namespaces,
          );
    
      XmlElement toXmlElement({
        Map<String, String?> namespaces = const {},
      }) =>
          _$TitleToXmlElement(
            this,
            namespaces: namespaces,
          );
    }
    
  5. Add a part directive to the file that contains the classes.
    part 'example.g.dart';
    
  6. Add the required package dependencies to your project.
    dart pub add xml xml_annotation dev:build_runner dev:xml_serializable
    
  7. Run the build runner to generate the serializer code.
    dart run build_runner build
    
  8. Verify that the generated serializer output is as expected.
    // GENERATED CODE - DO NOT MODIFY BY HAND
    
    part of 'example.dart';
    
    // **************************************************************************
    // XmlEnumGenerator
    // **************************************************************************
    
    const $LanguageEnumMap = {
      Language.mandarin: 'Mandarin',
      Language.spanish: 'Spanish',
      Language.english: 'English',
      Language.hindi: 'Hindi',
      Language.bengali: 'Bengali'
    };
    
    // **************************************************************************
    // XmlSerializableGenerator
    // **************************************************************************
    
    void _$BookBuildXmlChildren(Book instance, XmlBuilder builder,
        {Map<String, String> namespaces = const {}}) {
      final title = instance.title;
      final titleSerialized = title;
      builder.element('title', nest: () {
        if (titleSerialized != null) {
          titleSerialized.buildXmlChildren(builder, namespaces: namespaces);
        }
      });
      final authors = instance.authors;
      final authorsSerialized = authors;
      if (authorsSerialized != null) {
        for (final value in authorsSerialized) {
          builder.element('author', nest: () {
            builder.text(value);
          });
        }
      }
      final price = instance.price;
      final priceSerialized = price;
      builder.element('price', isSelfClosing: false, nest: () {
        if (priceSerialized != null) {
          builder.text(priceSerialized);
        }
      });
    }
    
    void _$BookBuildXmlElement(Book instance, XmlBuilder builder,
        {Map<String, String> namespaces = const {}}) {
      builder.element('book', namespaces: namespaces, nest: () {
        instance.buildXmlChildren(builder, namespaces: namespaces);
      });
    }
    
    Book _$BookFromXmlElement(XmlElement element) {
      final title = element.getElement('title');
      final authors = element
          .getElements('author')
          ?.map((e) => e.getText())
          .whereType<String>();
      final price = element.getElement('price')?.getText();
      return Book(
          title: title != null ? Title.fromXmlElement(title) : null,
          authors: authors?.toList(),
          price: price);
    }
    
    List<XmlAttribute> _$BookToXmlAttributes(Book instance,
        {Map<String, String?> namespaces = const {}}) {
      final attributes = <XmlAttribute>[];
      return attributes;
    }
    
    List<XmlNode> _$BookToXmlChildren(Book instance,
        {Map<String, String?> namespaces = const {}}) {
      final children = <XmlNode>[];
      final title = instance.title;
      final titleSerialized = title;
      final titleConstructed = XmlElement(
          XmlName('title'),
          titleSerialized?.toXmlAttributes(namespaces: namespaces) ?? [],
          titleSerialized?.toXmlChildren(namespaces: namespaces) ?? []);
      children.add(titleConstructed);
      final authors = instance.authors;
      final authorsSerialized = authors;
      final authorsConstructed = authorsSerialized
          ?.map((e) => XmlElement(XmlName('author'), [], [XmlText(e)]));
      if (authorsConstructed != null) {
        children.addAll(authorsConstructed);
      }
      final price = instance.price;
      final priceSerialized = price;
      final priceConstructed = XmlElement(XmlName('price'), [],
          priceSerialized != null ? [XmlText(priceSerialized)] : [], false);
      children.add(priceConstructed);
      return children;
    }
    
    XmlElement _$BookToXmlElement(Book instance,
        {Map<String, String?> namespaces = const {}}) {
      return XmlElement(
          XmlName('book'),
          [
            ...namespaces.toXmlAttributes(),
            ...instance.toXmlAttributes(namespaces: namespaces)
          ],
          instance.toXmlChildren(namespaces: namespaces));
    }
    
    void _$BookshelfBuildXmlChildren(Bookshelf instance, XmlBuilder builder,
        {Map<String, String> namespaces = const {}}) {
      final books = instance.books;
      final booksSerialized = books;
      if (booksSerialized != null) {
        for (final value in booksSerialized) {
          builder.element('book', nest: () {
            value.buildXmlChildren(builder, namespaces: namespaces);
          });
        }
      }
      final price = instance.price;
      final priceSerialized = price;
      if (priceSerialized != null) {
        builder.element('price', nest: () {
          builder.text(priceSerialized);
        });
      }
    }
    
    void _$BookshelfBuildXmlElement(Bookshelf instance, XmlBuilder builder,
        {Map<String, String> namespaces = const {}}) {
      builder.element('bookshelf', namespaces: namespaces, nest: () {
        instance.buildXmlChildren(builder, namespaces: namespaces);
      });
    }
    
    Bookshelf _$BookshelfFromXmlElement(XmlElement element) {
      final books = element.getElements('book');
      final price = element.getElement('price')?.getText();
      return Bookshelf(
          books: books?.map((e) => Book.fromXmlElement(e)).toList(), price: price);
    }
    
    List<XmlAttribute> _$BookshelfToXmlAttributes(Bookshelf instance,
        {Map<String, String?> namespaces = const {}}) {
      final attributes = <XmlAttribute>[];
      return attributes;
    }
    
    List<XmlNode> _$BookshelfToXmlChildren(Bookshelf instance,
        {Map<String, String?> namespaces = const {}}) {
      final children = <XmlNode>[];
      final books = instance.books;
      final booksSerialized = books;
      final booksConstructed = booksSerialized?.map((e) => XmlElement(
          XmlName('book'),
          e.toXmlAttributes(namespaces: namespaces),
          e.toXmlChildren(namespaces: namespaces)));
      if (booksConstructed != null) {
        children.addAll(booksConstructed);
      }
      final price = instance.price;
      final priceSerialized = price;
      final priceConstructed = priceSerialized != null
          ? XmlElement(XmlName('price'), [], [XmlText(priceSerialized)])
          : null;
      if (priceConstructed != null) {
        children.add(priceConstructed);
      }
      return children;
    }
    
    XmlElement _$BookshelfToXmlElement(Bookshelf instance,
        {Map<String, String?> namespaces = const {}}) {
      return XmlElement(
          XmlName('bookshelf'),
          [
            ...namespaces.toXmlAttributes(),
            ...instance.toXmlAttributes(namespaces: namespaces)
          ],
          instance.toXmlChildren(namespaces: namespaces));
    }
    
    void _$TitleBuildXmlChildren(Title instance, XmlBuilder builder,
        {Map<String, String> namespaces = const {}}) {
      final language = instance.language;
      final languageSerialized =
          language != null ? $LanguageEnumMap[language]! : null;
      if (languageSerialized != null) {
        builder.attribute('lang', languageSerialized);
      }
      final text = instance.text;
      final textSerialized = text;
      if (textSerialized != null) {
        builder.text(textSerialized);
      }
    }
    
    void _$TitleBuildXmlElement(Title instance, XmlBuilder builder,
        {Map<String, String> namespaces = const {}}) {
      builder.element('title', namespaces: namespaces, nest: () {
        instance.buildXmlChildren(builder, namespaces: namespaces);
      });
    }
    
    Title _$TitleFromXmlElement(XmlElement element) {
      final language = element.getAttribute('lang');
      final text = element.getText();
      return Title(
          language: language != null
              ? $LanguageEnumMap.entries
                  .singleWhere(
                      (languageEnumMapEntry) =>
                          languageEnumMapEntry.value == language,
                      orElse: () => throw ArgumentError(
                          '`$language` is not one of the supported values: ${$LanguageEnumMap.values.join(', ')}'))
                  .key
              : null,
          text: text);
    }
    
    List<XmlAttribute> _$TitleToXmlAttributes(Title instance,
        {Map<String, String?> namespaces = const {}}) {
      final attributes = <XmlAttribute>[];
      final language = instance.language;
      final languageSerialized =
          language != null ? $LanguageEnumMap[language]! : null;
      final languageConstructed = languageSerialized != null
          ? XmlAttribute(XmlName('lang'), languageSerialized)
          : null;
      if (languageConstructed != null) {
        attributes.add(languageConstructed);
      }
      return attributes;
    }
    
    List<XmlNode> _$TitleToXmlChildren(Title instance,
        {Map<String, String?> namespaces = const {}}) {
      final children = <XmlNode>[];
      final text = instance.text;
      final textSerialized = text;
      final textConstructed =
          textSerialized != null ? XmlText(textSerialized) : null;
      if (textConstructed != null) {
        children.add(textConstructed);
      }
      return children;
    }
    
    XmlElement _$TitleToXmlElement(Title instance,
        {Map<String, String?> namespaces = const {}}) {
      return XmlElement(
          XmlName('title'),
          [
            ...namespaces.toXmlAttributes(),
            ...instance.toXmlAttributes(namespaces: namespaces)
          ],
          instance.toXmlChildren(namespaces: namespaces));
    }
    
9
likes
150
points
18.1k
downloads

Publisher

verified publisherthomasclark.dev

Weekly Downloads

Automatically generate code for converting to and from XML by annotating Dart classes.

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

analyzer, build, build_config, recase, source_gen, source_helper, xml, xml_annotation

More

Packages that depend on xml_serializable