'The argument type 'Iterable<String>' can't be assigned to the parameter type 'List<Image>'. with an Xml file

I am trying to parse an nested XML file with the "xml" package. https://pub.dev/packages/xml

however I have the following error :

The argument type 'Iterable' can't be assigned to the parameter type 'List'.

the unnested part is shown ("category" and "email") but the nested part is not shown ("image") of the xml file.

the xml file

<!--contact.xml-->
<data>
    <category>projet</category>
    <email>[email protected]</email>
    <image>
        <link>http://image.com/myimage.jpg</link>
        <description>my image</description>
        <type>JPG</type>
    </image>
</data>

the model Class

//Contact.dart
class Contact {
  String _category;
  String _email;
  List<Image> _image;

  Contact(this._category, this._email, this._image);
  factory Contact.fromJSON(Map<String, dynamic> json) {
    return Contact(json["category"], json["email"], json["image"]);
  }
  get category => this._category;
  get email => this._email;
  get image => this._image;
}

class Image {
  String _link;
  String _description;
  String _type;

  Image(this._link, this._description, this._type);
  factory Image.fromJSON(Map<String, dynamic> json) {
    return Image(
      json["link"],
      json["description"],
      json["type"],
    );
  }
  get title => this._link;
  get url => this._description;
  get link => this._type;
}

the part of the code that does not work

//main.dart
  Future<List<Contact>> getContactsFromXML(BuildContext context) async {
    String xmlString = await DefaultAssetBundle.of(context).loadString("assets/data/contact.xml");
    var raw = xml.parse(xmlString);
    var elements = raw.findAllElements("data");
    return elements.map((element) {
      return Contact(
        element.findElements('category').first.text, //<-- OK
        element.findElements("email").first.text, //<-- OK
        element.findAllElements("image").map((e) => e.findElements("link").single.text), //<-- Error
        element.findAllElements("image").map((e) => e.findElements("description").single.text),//<-- Error
        element.findAllElements("image").map((e) => e.findElements("type").single.text)//<-- Error
      );
    }).toList();
  }

thanks for your help



Solution 1:[1]

The constructor of your Contact class takes 3 arguments, yet you seem to pass 5? Also I don't see where you create the Image object?

I think you need to change the code that constructs the Contact to something along:

return Contact(
    element.findElements('category').first.text, 
    element.findElements("email").first.text, 
    element.findAllElements("image").map((e) => Image( // <-- create image
       e.findElements("link").single.text, 
       e.findElements("description").single.text,
       e.findElements("type").single.text,
    )).toList(), // <-- convert to list
);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Lukas Renggli