tnc1997 / dart-xml-serializable Goto Github PK
View Code? Open in Web Editor NEWGenerates utilities to aid in serializing to/from XML.
Home Page: https://pub.dev/packages/xml_serializable
License: MIT License
Generates utilities to aid in serializing to/from XML.
Home Page: https://pub.dev/packages/xml_serializable
License: MIT License
The current version of analyzer used in xml_serializable is creating issues with various other packages like custom_lint, riverpod_lint, riverpod_generator etc. Please update the library to the latest version to resolve the conflicts.
Describe the bug
When declaring a variable using a prefixed class name, the prefix is not used in the resulting generated file after running build_runner.
Current behavior
Steps to reproduce the behavior:
import 'package:my_software/device.dart' as device;
class ServiceCapabilities {
@annotation.XmlElement(
name: 'Capabilities',
namespace: 'http://www.onvif.org/ver10/device/wsdl',
)
final device.Capabilities? deviceCapabilities;
build_runner
to generate code.Expected behavior
It's expected that the generated code would include the device
prefix.
ServiceCapabilities _$ServiceCapabilitiesFromXmlElement(XmlElement element) {
final deviceCapabilities = element.getElement('Capabilities',
namespace: 'http://www.onvif.org/ver10/device/wsdl');
return ServiceCapabilities(
deviceCapabilities: deviceCapabilities != null
? device.Capabilities.fromXmlElement(deviceCapabilities)
: null);
}
The actual code generated has Capabilities.fromXmlElement(deviceCapabilities)
when the actual correct code isdevice.Capabilities.fromXmlElement(deviceCapabilities)
(as shown above).
Is your feature request related to a problem? Please describe.
I have a class with computed fields (getters). However, when I try to add a getter with computed logic, the generator fails with the error:
[SEVERE] xml_serializable on lib/src/api/login/models/computed.dart:
Invalid argument (element): `isValid` does not have a supported annotation. Add an annotation of the form `@XmlAttribute()`, `@XmlElement()`, or `@XmlText()` to `isValid`.: Instance of 'FieldElementImpl'
Here is the corresponding code:
@xml.XmlSerializable(createMixin: true)
@xml.XmlRootElement(name: 'Computed')
@immutable
class Computed with _$ComputedXmlSerializableMixin {
@xml.XmlText()
final String value;
bool get isValid => value != 'invalid';
const Computed({required this.value});
factory Computed.fromXmlElement(XmlElement element) =>
_$ComputedFromXmlElement(element);
}
Describe the solution you'd like
It would be nice if there was a XmlIgnore
annotation (or something similar) so we could simply exclude such members from the generator:
@xml.XmlIgnore()
bool get isValid => value != 'invalid';
Describe alternatives you've considered
Another alternative would be to only take members with a Xml annotation into account and implicitly ignore members without it, but I think I would prefer an "ignore" annotation.
Hi,
We lately ran into an issue with a an XML file that contains a mandatory element but that one contains an "empty string" like this.
<?xml version="1.0"?>
<test>
<notnull></notnull>
</test>
The element is there but it is empty. This cannot be parsed and raises an exception. The problem is that the getter code that is generated converts empty string to "null" in dart but at the same time puts a ! on it.
The model to process this XML looks like this:
import 'package:xml/xml.dart';
import 'package:xml_annotation/xml_annotation.dart' as annotation;
part 'xml_null_test.g.dart';
@annotation.XmlRootElement(name: 'test')
@annotation.XmlSerializable()
class XMLNullTest {
@annotation.XmlElement(name: 'notnull')
String notnull;
XMLNullTest({required this.notnull});
factory XMLNullTest.fromXmlElement(XmlElement element) =>
_$XMLNullTestFromXmlElement(element);
...
As you can see the field notnull is of type String and is mandatory. But when we parse the XML above it fails with an exception.
the reason for this is the way how the getter is generated. It is generated like this:
final notnull = element.getElement('notnull')!.getText()!;
The method getText() returns null when the string is "empty" in the XML.
See: xml_text_getter_generator.dart
and getText extension method
Null vs "empty string" is not clearly specified in XML and there are many problems related to this. What you did is not "wrong" as it is not clear if an empty element should be interpreted as null or as "empty string". But the problem is that there is no way I could workaround this issue cleanly (only by making my field String? in my code but this is also not nice).
I would propose to make this somehow configurable if empty elements should be treated as null or as "empty strings".
Then it should generate this code:
final notnull = element.getElement('notnull')!.getText() ?? '';
If you do not want to change this as this might be a compatibility issue with existing code, then we could allow to select this via a flag on the @annotation.XmlSerializable() for the whole XML via a new flag.
Here a test case to reproduce this with the simple model class from above. It throws an exception when parsing the XML:
test('Null XML', () {
const test = '''
<?xml version="1.0"?>
<test>
<notnull></notnull>
</test>''';
final document = XmlDocument.parse(test);
final model = XMLNullTest.fromXmlElement(document.rootElement);
expect(model, isNotNull);
});
Testing started at 09:40 ...
package:amos_mobile_etlb/src/test/xml_null_test.g.dart 29:59 _$XMLNullTestFromXmlElement
package:amos_mobile_etlb/src/test/xml_null_test.dart 15:7 new XMLNullTest.fromXmlElement
test\xml_null_test.dart 15:31 main.
Null check operator used on a null value
I have two classes named Student and Schoolclass.
Student extends Schoolclass so that the class Student can use the parameters gradeLevel and teacher.
Student class:
@annotation.XmlRootElement(name: 'Student')
@annotation.XmlSerializable()
class Student extends Schoolclass {
@annotation.XmlAttribute(name: 'name')
String name;
Student({
required this.name,
required int gradeLevel,
required String teacher,
}) : super(gradeLevel: gradeLevel, teacher: teacher,);
factory Student.fromXmlElement(XmlElement element) =>
_$StudentFromXmlElement(element);
@override
String toString() {
return 'Student{name: $name, gradeLevel: $gradeLevel, teacher: $teacher}';
}
void buildXmlChildren(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_$StudentBuildXmlChildren(
this,
builder,
namespaces: namespaces,
);
void buildXmlElement(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_$StudentBuildXmlElement(
this,
builder,
namespaces: namespaces,
);
List<XmlAttribute> toXmlAttributes({
Map<String, String?> namespaces = const {},
}) =>
_$StudentToXmlAttributes(
this,
namespaces: namespaces,
);
List<XmlNode> toXmlChildren({
Map<String, String?> namespaces = const {},
}) =>
_$StudentToXmlChildren(
this,
namespaces: namespaces,
);
XmlElement toXmlElement({
Map<String, String?> namespaces = const {},
}) =>
_$StudentToXmlElement(
this,
namespaces: namespaces,
);
}
Schoolclass class:
@annotation.XmlRootElement(name: 'Schoolclass')
@annotation.XmlSerializable()
abstract class Schoolclass {
@annotation.XmlAttribute(name: 'gradeLevel')
int gradeLevel;
@annotation.XmlAttribute(name: 'teacher')
String teacher;
Schoolclass ({
required this.gradeLevel,
required this.teacher,
});
factory Schoolclass.fromXmlElement(XmlElement element) =>
_$SchoolclassFromXmlElement(element);
@override
String toString() {
return 'Schoolclass{gradeLevel: $gradeLevel, teacher: $teacher}';
}
void buildXmlChildren(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_$SchoolclassBuildXmlChildren(
this,
builder,
namespaces: namespaces,
);
void buildXmlElement(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_$SchoolclassBuildXmlElement(
this,
builder,
namespaces: namespaces,
);
List<XmlAttribute> toXmlAttributes({
Map<String, String?> namespaces = const {},
}) =>
_$SchoolclassToXmlAttributes(
this,
namespaces: namespaces,
);
List<XmlNode> toXmlChildren({
Map<String, String?> namespaces = const {},
}) =>
_$SchoolclassToXmlChildren(
this,
namespaces: namespaces,
);
XmlElement toXmlElement({
Map<String, String?> namespaces = const {},
}) =>
_$SchoolclassToXmlElement(
this,
namespaces: namespaces,
);
}
When generating the serializer with flutter packages pub run build_runner build, I get the following output:
void _$StudentBuildXmlChildren(Student instance, XmlBuilder builder,
{Map<String, String> namespaces = const {}}) {
final name = instance.name;
final nameSerialized = name;
builder.attribute('name', nameSerialized);
}
void _$StudentBuildXmlElement(Student instance, XmlBuilder builder,
{Map<String, String> namespaces = const {}}) {
builder.element('Student', namespaces: namespaces, nest: () {
instance.buildXmlChildren(builder, namespaces: namespaces);
});
}
Student _$StudentFromXmlElement(XmlElement element) {
final name = element.getAttribute('name')!;
return Student(name: name);
}
List<XmlAttribute> _$StudentToXmlAttributes(Student instance,
{Map<String, String?> namespaces = const {}}) {
final attributes = <XmlAttribute>[];
final name = instance.name;
final nameSerialized = name;
final nameConstructed = XmlAttribute(XmlName('name'), nameSerialized);
attributes.add(nameConstructed);
return attributes;
}
List<XmlNode> _$StudentToXmlChildren(Student instance,
{Map<String, String?> namespaces = const {}}) {
final children = <XmlNode>[];
return children;
}
XmlElement _$StudentToXmlElement(Student instance,
{Map<String, String?> namespaces = const {}}) {
return XmlElement(
XmlName('Student'),
[
...namespaces.toXmlAttributes(),
...instance.toXmlAttributes(namespaces: namespaces)
],
instance.toXmlChildren(namespaces: namespaces));
}
void _$SchoolclassBuildXmlChildren(Schoolclass instance, XmlBuilder builder,
{Map<String, String> namespaces = const {}}) {
final gradeLevel = instance.gradeLevel;
final gradeLevelSerialized = gradeLevel.toString();
builder.attribute('gradeLevel', gradeLevelSerialized);
final teacher = instance.teacher;
final teacherSerialized = teacher;
builder.attribute('teacher', teacherSerialized);
}
void _$SchoolclassBuildXmlElement(Schoolclass instance, XmlBuilder builder,
{Map<String, String> namespaces = const {}}) {
builder.element('Schoolclass', namespaces: namespaces, nest: () {
instance.buildXmlChildren(builder, namespaces: namespaces);
});
}
Schoolclass _$SchoolclassFromXmlElement(XmlElement element) {
final gradeLevel = element.getAttribute('gradeLevel')!;
final teacher = element.getAttribute('teacher')!;
return Schoolclass(gradeLevel: int.parse(gradeLevel), teacher: teacher);
}
List<XmlAttribute> _$SchoolclassToXmlAttributes(Schoolclass instance,
{Map<String, String?> namespaces = const {}}) {
final attributes = <XmlAttribute>[];
final gradeLevel = instance.gradeLevel;
final gradeLevelSerialized = gradeLevel.toString();
final gradeLevelConstructed =
XmlAttribute(XmlName('gradeLevel'), gradeLevelSerialized);
attributes.add(gradeLevelConstructed);
final teacher = instance.teacher;
final teacherSerialized = teacher;
final teacherConstructed =
XmlAttribute(XmlName('teacher'), teacherSerialized);
attributes.add(teacherConstructed);
return attributes;
}
List<XmlNode> _$SchoolclassToXmlChildren(Schoolclass instance,
{Map<String, String?> namespaces = const {}}) {
final children = <XmlNode>[];
return children;
}
XmlElement _$SchoolclassToXmlElement(Schoolclass instance,
{Map<String, String?> namespaces = const {}}) {
return XmlElement(
XmlName('Schoolclass'),
[
...namespaces.toXmlAttributes(),
...instance.toXmlAttributes(namespaces: namespaces)
],
instance.toXmlChildren(namespaces: namespaces));
}
The function _$StudentFromXmlElement() does not feature the parameters of the extended class and because the parameters are required by the constructor the function will not work.
Student _$StudentFromXmlElement(XmlElement element) {
final name = element.getAttribute('name')!;
return Student(name: name);
}
How can polymorphism be achieved with dart-xml-serializable?
Is your feature request related to a problem? Please describe.
As a developer I would like to serialize and deserialize XML CDATA in addition to XML text.
Describe the solution you'd like
I would like the xml_annotation
package to export an XmlCDATA
annotation.
Additional context
#45
Is your feature request related to a problem? Please describe.
It is not possible to rename fields in a class to a case that isn't camel case without having to specify the name of each field.
Describe the solution you'd like
I would like to see a fieldRename
option on XmlSerializable
that allows for the renaming of fields in a class to the specified case.
Describe alternatives you've considered
The workaround at the moment is to specify the name of each field using the XmlAttribute
and XmlElement
annotations.
To preface this, I have no idea what I'm doing, so, it's probably my fault. I'm writing a grade viewer app, which pulls a very large XML file from the gradebook service my school uses. I've got that stored in a string, and then followed the instructions in the docs, so I have a very large file with all the classes and things properly annotated. However, when I run the builder, the buildXmlElement and toXmlElement methods generated for only half of the classes.
Here is a sample of the XML I am deserializing:
<?xml version="1.0" encoding="UTF-8"?>
<Gradebook xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Type="Traditional" ErrorMessage="" HideStandardGraphInd="false" HideMarksColumnElementary="true" HidePointsColumnElementary="false" HidePercentSecondary="false" DisplayStandardsData="true" GBStandardsTabDefault="true">
<ReportingPeriods>
<ReportPeriod Index="0" GradePeriod="Quarter 1" StartDate="9/1/2022" EndDate="11/7/2022" />
<ReportPeriod Index="1" GradePeriod="Semester 1 Final" StartDate="11/8/2022" EndDate="1/27/2023" />
<ReportPeriod Index="2" GradePeriod="Quarter 3" StartDate="1/30/2023" EndDate="4/20/2023" />
<ReportPeriod Index="3" GradePeriod="Semester 2 FInal" StartDate="4/21/2023" EndDate="6/22/2023" />
</ReportingPeriods>
<ReportingPeriod GradePeriod="Semester 2 FInal" StartDate="4/21/2023" EndDate="6/22/2023" />
<Courses>
<Course UsesRichContent="true" Period="1" Title="AP Comp Sci Princ" Room="xxx" Staff="xxxx" StaffEMail="xxxxxx@xxxxxorg" StaffGU="xxxxxxxxx" HighlightPercentageCutOffForProgressBar="50">
...
And part of the class (it's too long to share the whole thing, though I could put it up on github if that would be helpful):
@annotation.XmlElement(name: "GradeBook")
@annotation.XmlSerializable()
class GradeBook {
@annotation.XmlElement(name: "ReportingPeriods")
ReportingPeriods? reportingPeriods;
@annotation.XmlElement(name: "ReportingPeriod")
ReportingPeriod? reportingPeriod;
@annotation.XmlElement(name: "Courses")
Courses? courses;
GradeBook({
this.reportingPeriods,
this.reportingPeriod,
this.courses
});
@override
String toString() {
return 'GradeBook {'
' Reporting Periods: $reportingPeriods'
' Reporting Period: $reportingPeriod'
' Courses: $courses'
'}';
}
factory GradeBook.fromXmlElement(XmlElement element) =>
_$GradeBookFromXmlElement(element);
void buildXmlChildren(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_$GradeBookBuildXmlChildren(
this,
builder,
namespaces: namespaces,
);
...
I'm not sure why it's not working, I also only need to deserialize xml, so if this doesn't matter for that then I will just delete the ones that didn't generate and move on. Secondly, how do I use this? Now that there is a nice interface, what should I do to turn my String containing all the XML into Dart objects?
Thank you so much in advanced! You're a saint for almost single-handedly maintaining this library it's super useful, and surprisingly easy to setup despite the boilerplate.
Describe the bug
Created List of null class object but element is null (selfclosed)
Help me please, may be I do smt wrong.
Current behavior
<UiMenuItem>
<Id>0</Id>
<Name>one</Name>
<Hint/>
<Url/>
<IconUrl>https://test.com</IconUrl>
<Kind>SubMenu</Kind>
<Action>Undefined</Action>
<Items>
<UiMenuItem>
<Id>13692716</Id>
<Name>qwdqw</Name>
<Hint/>
<Url/>
<IconUrl>https://test.com</IconUrl>
<Kind>Action</Kind>
<Action>Open</Action>
<Items/>
</UiMenuItem>
<UiMenuItem>
<Id>2559307</Id>
<Name>dqwdqw</Name>
<Hint/>
<Url/>
<IconUrl>https://test.com</IconUrl>
<Kind>Action</Kind>
<Action>SendFundsToTelepayContractorProfile</Action>
<Items/>
</UiMenuItem>
</Items>
</UiMenuItem>
@annotation.XmlRootElement(name: 'UiMenuItem')
@annotation.XmlSerializable()
class UiMenuItem {
@annotation.XmlElement(name: 'Id')
int id;
@annotation.XmlElement(name: 'Name')
String? name;
@annotation.XmlElement(name: 'Hint')
String? hint;
@annotation.XmlElement(name: 'Url')
String? url;
@annotation.XmlElement(name: 'IconUrl')
String? iconUrl;
@annotation.XmlElement(name: 'Kind')
String kind;
@annotation.XmlElement(name: 'Action')
String action;
@annotation.XmlElement(name: 'Items')
List<UiMenuItem>? items;
UiMenuItem({
required this.id,
required this.name,
required this.hint,
required this.url,
required this.iconUrl,
required this.kind,
required this.action,
required this.items,
});
factory UiMenuItem.fromXmlElement(XmlElement element) => _$UiMenuItemFromXmlElement(element);
void buildXmlChildren(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_$UiMenuItemBuildXmlChildren(
this,
builder,
namespaces: namespaces,
);
void buildXmlElement(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_$UiMenuItemBuildXmlElement(
this,
builder,
namespaces: namespaces,
);
List<XmlAttribute> toXmlAttributes({
Map<String, String?> namespaces = const {},
}) =>
_$UiMenuItemToXmlAttributes(
this,
namespaces: namespaces,
);
List<XmlNode> toXmlChildren({
Map<String, String?> namespaces = const {},
}) =>
_$UiMenuItemToXmlChildren(
this,
namespaces: namespaces,
);
XmlElement toXmlElement({
Map<String, String?> namespaces = const {},
}) =>
_$UiMenuItemToXmlElement(
this,
namespaces: namespaces,
);
}
So, I get from element: < Items / >" List of one element :
id: null,
name: null,
hint: null,
url: null,
action: null,
kind: null,
items: null
Expected behavior
get items: null
or better get empty List, like a items: []
Describe the bug
The generated code is unable to handle enum lists, as multiple methods use e
, overshadowing each other.
Current behavior
Consider the following code:
@xml.XmlEnum()
enum AccessType {
@xml.XmlValue('SiteA')
siteA,
@xml.XmlValue('SiteBeta')
siteB;
}
@xml.XmlSerializable(createMixin: true)
@xml.XmlRootElement(name: 'Permissions')
class Permissions with _$PermissionsXmlSerializableMixin {
@xml.XmlElement(name: 'Access')
final List<AccessType>? accessTypes;
const Permissions({
required this.accessTypes,
});
factory Permissions.fromXmlElement(XmlElement element) =>
_$PermissionsFromXmlElement(element);
}
The generator will generate the following snippet for the _$PermissionsFromXmlElement
method:
Permissions _$PermissionsFromXmlElement(XmlElement element) {
final accessTypes = element
.getElements('Access')
?.map((e) => e.getText())
.whereType<String>();
return Permissions(
accessTypes: accessTypes
?.map((e) => _$AccessTypeEnumMap.entries // HERE: e is defined
.singleWhere((e) => e.value == e, // HERE: e is defined again
orElse: () => throw ArgumentError(
'`$e` is not one of the supported values: ${_$AccessTypeEnumMap.values.join(', ')}'))
.key)
.toList());
}
As you can see, e
i used both in map
and singleWhere
, which leads to the second always being false (as e.value == e
is obviously never true).
Expected behavior
It should work correctly and thus use two different variables. Recommendation: Use long names like element
and enumEntry
. Or even better generated names like accessTypesElement
and accessTypeEnumEntry
.
Is your feature request related to a problem? Please describe.
This package currently only supports serializing String
types and any custom types that are annotated with XmlSerializable()
.
Describe the solution you'd like
As a developer I would like this package to serialize types such as int
and bool
so that I do not have to implement that logic.
Describe alternatives you've considered
The current workaround is for the consuming application to implement logic to convert String
types to other common types.
Additional context
This change will involve refactoring the XmlSerializableGenerator
and creating SerializerGenerator
s that abstract the logic.
Unless I mis-read your docs, nowhere does it state step by step how a beginner would use your project. You mention builders without explaining how to run a builder. Maybe you could write something like:
add build_runner to your dev_dependencies, then run
dart run build_runner build
to generate the files.
In the readme, you show an example piece of code and the resulting generated file. It'd be nice to start by showing the XML you're trying to model.
I think resolving #31 would go a long way to make it beginner friendly.
Is your feature request related to a problem? Please describe.
There are always boilerplate code for buildXmlChildren
, buildXmlElement
, toXmlAttributes
, toXmlChildren
and toXmlElement
.
Describe the solution you'd like
Put generated methods into private class
and create mixin
which will substitute these methods.
Proposed API will looks like:
import 'package:xml/xml.dart';
import 'package:xml_annotation/xml_annotation.dart' as annotation;
part 'example.g.dart';
@annotation.XmlRootElement(name: 'person')
@annotation.XmlSerializable()
class Person with XMLParserMixin<Person, _$PersonParser> {
@annotation.XmlElement(name: 'name')
final String? name;
Person({
this.name,
});
static const _personParser = _$PersonParser();
@override
_$PersonParser get _parser => _personParser;
factory Person.fromXmlElement(XmlElement element) =>
_personParser.fromXmlElement(element);
}
Describe alternatives you've considered
I see no better solutions for now.
Additional context
Here's an example implementation I came up with:
/// File code
class Person with XMLParserMixin<Person, _$PersonParser> {
static const _personParser = _$PersonParser();
@override
_$PersonParser get _parser => _personParser;
String? name;
Person({
this.name,
});
factory Person.fromXmlElement(XmlElement element) =>
_personParser.fromXmlElement(element);
// Other methods are implemented via mixin
}
/// Auxiliary code
abstract class XMLSerializableParser<T> {
const XMLSerializableParser();
T fromXmlElement(XmlElement element);
void buildXmlChildren(
T instance,
XmlBuilder builder, {
Map<String, String> namespaces = const {},
});
// and so on...
}
mixin XMLParserMixin<T, Parser extends XMLSerializableParser<T>> {
Parser get _parser;
void buildXmlChildren(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_parser.buildXmlChildren(
this as T,
builder,
namespaces: namespaces,
);
// and so on...
}
/// Generated code
class _$PersonParser extends XMLSerializableParser<Person> {
const _$PersonParser() : super();
@override
Person fromXmlElement(XmlElement element) {
print('called fromXmlElement of _\$PersonParser');
return Person();
}
@override
void buildXmlChildren(
Person instance,
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) {
print('called buildXmlChildren of _\$PersonParser');
}
}
/// Test
void main(List<String> arguments) async {
final person = Person.fromXmlElement(XmlElement());
person.buildXmlChildren(XmlBuilder());
}
If I use the XML like:
<?xml version="1.0"?>
<bookshelf>
<book>
<title lang="English"><RandomUnknownTag>XML Pocket Reference</RandomUnknownTag ></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>
Will it be possible to have an @ InnerXml() tag
in future request.
which will help to set the value of of text in title class to <RandomUnknownTag>XML Pocket Reference</RandomUnknownTag>
as an innerXml String.
and back to <RandomUnknownTag>XML Pocket Reference</RandomUnknownTag>
when generating XML.
If it is already possible and I'm missing this, Please do let me know how could I achieve this.
The lowest version of analyzer
currently supported is 2.0.0 and the highest version is 4.7.0.
There have been a number of deprecations in this version range such as DartType.element
.
I propose upgrading the version constraint of analyzer
to >=4.6.0 <6.0.0
in this package.
This will allow a seamless migration internally from DartType.element
to DartType.element2
.
Unfortunately this does mean that support for all versions lower than 4.6.0 will be removed.
I use the library now for a few months and it really works great.
Now, for the first time, I had a situation, where I needed to add a property to the class, which should not be used during serialization process. I have seen this is possible for JSON, but it seems to be not integrated to the xml serializable library yet.
Example:
@annotation.XmlRootElement(name: 'IMAGE')
@annotation.XmlSerializable()
class BlogEntryAssetImage {
@annotation.XmlElement(name: 'DATA')
BlogEntryAssetImageData? blogEntryAssetImageData;
BlogEntryAssetImage({
this.blogEntryAssetImageData,
this.image,
});
//also create an image provider for later use in the UI
@annotation.XmlElement(ignore: true)
ImageProvider? image;
factory BlogEntryAssetImage.fromXmlElement(XmlElement element) =>
_$BlogEntryAssetImageFromXmlElement(element);
...
the ImageProvider property is used later (when the XML is read) to create an instance of ImageProvider which represents the image stored within the blogEntryAssetImageData text (encoded as base64). It should just be ignored when running flutter pub run build_runner build - in fact, it works fine when the property is added after running flutter pub run build_runner build, but next time it is called, I get the message
image
does not have a supported annotation. Add an annotation of the form @XmlAttribute()
, @XmlElement()
, or @XmlText()
to image
.: Instance of 'FieldElementImpl'
Is there already any way to add properties which can be ignored or is this feature not implemented at all?
Thank you for your help,
regards
Robert
I tried writing the simplest class:
import 'package:xml_annotation/xml_annotation.dart' as annotation;
part 'character.g.dart';
@annotation.XmlRootElement(name: 'character')
@annotation.XmlSerializable()
class Character {}
And ran the generator. It generated the character.g.dart class but it had a compile error:
The method 'buildXmlChildren' isn't defined for the type 'Character'. Try correcting the name to the name of an existing method, or defining a method named 'buildXmlChildren'.
It would be nice to handle the simplest use cases to allow us to write even less boilerplate code. Judging from your readme example, i would still need to implement a few more methods for it to compile.
Is your feature request related to a problem? Please describe.
As a developer I would like to provide an XmlConverter
to control the serialization of data types.
Describe the solution you'd like
I would like a solution that is similar to the JsonConverter
from the json_annotation
package.
Additional context
https://github.com/google/json_serializable.dart/blob/master/json_annotation/lib/src/json_converter.dart
https://github.com/google/json_serializable.dart/blob/master/example/lib/json_converter_example.dart
Describe the bug
I have an XmlEnum
in one file and a XmlSerializable
in another file. Because the enum map is private, it cannot be used in the second file.
Current behavior
Steps to reproduce the behavior:
a.dart
with an XmlEnum
b.dart
with an XmlSerializable
Expected behavior
Enums should be serializable even when used across multiple files
I have a class named Student, which should have a name and book attribute.
The book attribute can correspond to different implementations. There are several classes that extend AbstractBook.
Student class:
@annotation.XmlRootElement(name: 'Student')
@annotation.XmlSerializable()
class Student {
@annotation.XmlAttribute(name: 'name')
String name;
@annotation.XmlElement(name: 'Book')
AbstractBook book;
Student({
required this.name,
required this.book,
});
factory Student.fromXmlElement(XmlElement element) =>
_$StudentFromXmlElement(element);
void buildXmlChildren(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_$StudentBuildXmlChildren(
this,
builder,
namespaces: namespaces,
);
void buildXmlElement(
XmlBuilder builder, {
Map<String, String> namespaces = const {},
}) =>
_$StudentBuildXmlElement(
this,
builder,
namespaces: namespaces,
);
List<XmlAttribute> toXmlAttributes({
Map<String, String?> namespaces = const {},
}) =>
_$StudentToXmlAttributes(
this,
namespaces: namespaces,
);
List<XmlNode> toXmlChildren({
Map<String, String?> namespaces = const {},
}) =>
_$StudentToXmlChildren(
this,
namespaces: namespaces,
);
XmlElement toXmlElement({
Map<String, String?> namespaces = const {},
}) =>
_$StudentToXmlElement(
this,
namespaces: namespaces,
);
}
Is it possible at the moment to easily and dynamically choose the name of the attribute inside the XML?
For example, the name should be "Math" if the object for AbstractBook is MathBook or "Chemistry" if the object is ChemistryBook.
Hello,
Could you upgrade the analyzer
to ^3.0.0 as it makes a conflict with Freezed Library
Thanks
Is your feature request related to a problem? Please describe.
I'd like to be able to parse enum
s (for example S3 Object#ChecksumAlgorithm is a clear enum
).
Also it would be nice if it would be possible to parse arbitrary type if it has factory
constructor parse(String string)
/static
function tryParse(String string)
or factory
constructor fromXmlElement(XmlElement element)
.
Describe the solution you'd like
Test if required type has has factory
constructor parse(String input)
or factory
constructor fromXmlElement(XmlElement element)
and use it.
Describe alternatives you've considered
Don't have any yet.
Additional context
Enum
from link could be like this:
enum ChecksumAlgorithm {
crc32('CRC32'),
crc32c('CRC32C'),
sha1('SHA1'),
sha256('SHA256');
const ChecksumAlgorithm(this.value);
factory ChecksumAlgorithm.fromXmlElement(XmlElement element) =>
values.firstWhere((_enum) => _enum.value == element.text);
final String value;
}
Describe the bug
After adding an XmlCDATA
annotation to a nullable field, a source code with compilation error is generated.
Current behavior
Add XmlCDATA
annotation to a nullable field, e.g.:
@annotation.XmlCDATA()
@annotation.XmlElement(name: 'DESC')
final String? description;
Generated source code is incorrect:
final descriptionConstructed =
descriptionSerialized != null ? XmlCDATA(descriptionSerialized) : null;
children.add(descriptionConstructed); // The argument type 'XmlCDATA?' can't be assigned to the parameter type 'XmlNode'.
Expected behavior
Code should compile ;)
I'm not sure, but it may be as simple as:
final descriptionConstructed =
descriptionSerialized != null ? XmlCDATA(descriptionSerialized) : null;
if (descriptionConstructed != null) {
children.add(descriptionConstructed);
}
The xml lib has very good Stream support.
It would be great if the generated code would also make use of that.
This would probably improve performance as the data could be deserialized asynchronously as it arrives.
Is your feature request related to a problem? Please describe.
To be able to map XML type "base64Binary", to Dart Uint8List
and vice-versa.
Describe the solution you'd like
Support "base64Binary" to be mapped to / from Uint8List
.
Describe alternatives you've considered
Working with plain strings and mapping to Dart type when needed.
I have the following structure:
<resourcetype>
<collection/>
</resourcetype>
In this case collection
never has any value and I only want to know if the element is present or not.
I can't figure out how I have to build my serializables to make this work.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.