在Dart/Flutter中解析一个巨大的(3Gb)XML

在Dart/Flutter中解析一个巨大的(3Gb)XML,xml,flutter,dart,xml-parsing,Xml,Flutter,Dart,Xml Parsing,我有一个站点,从中接收到一个巨大的XML文件。 我需要在Dart中将其解析为2个类 XML(它的一部分): UpdatedBook类更复杂,但这不是问题的范围 问题是,如何使用Dart XML包解析XML响应 它们有流函数的描述,但我不知道如何从中获取类 final url = Uri.parse('http://ip-api.com/xml/'); final request = await httpClient.getUrl(url); final response = await requ

我有一个站点,从中接收到一个巨大的XML文件。 我需要在Dart中将其解析为2个类

XML(它的一部分):

UpdatedBook类更复杂,但这不是问题的范围

问题是,如何使用Dart XML包解析XML响应

它们有流函数的描述,但我不知道如何从中获取类

final url = Uri.parse('http://ip-api.com/xml/');
final request = await httpClient.getUrl(url);
final response = await request.close();
final stream = response
    .transform(utf8.decoder)
    .transform(const XmlEventDecoder())
    .transform(const XmlNormalizer())
    .expand((events) => events)
    .forEach((event) => print(event));
那么,如何从流中获取类呢?

中的答案解释了如何将事件流(受
skipWhile
takeWhile
中的条件限制)转换为节点的子树(使用
XmlNodeDecoder

在这种情况下,它有点复杂:我们需要多次进入/退出跳过/参与部件。不幸的是,我不知道如何以优雅的方式使用Dart流实现这一点(使用一些Rx扩展可能更容易些?),但到目前为止,您可以编写:

响应
.变换(utf8.解码器)
.toXmlEvents()
.选择SubtreeEvents((事件)=>
event.name=='updated book'| | event.name=='removed book')
.toXmlNodes()
.flatte()
.其中((节点)=>节点为XmlElement)
.cast()
.map((元素){
if(element.name.qualified==“已删除的书本”){
退书(
id:element.getAttribute('id'),
...
));
}否则{
...
}
})
.forEach(印刷版);

虽然在有颤动的移动设备上读取和处理这样的数据是绝对可能的,但您可能要考虑预先在更强大的设备上预处理大量的数据。

和我还需要从XML流的第一行保留时间戳。您必须从流中解析它吗?为什么不接收整个响应并使用
XmlDocument.parse(String s)
解析它呢?它很大,大约3GB,我可以从RAM中取出。我还想知道如何为未来的项目从流中获取数据。我正在用clear Dart编写,所以我只需要从XML中获取数据并将其放到我的Firebase中,这样就不会有颤振和移动设备了。)
class RemovedBook {
    RemovedBook({
        this.id,
        this.uid,
        this.removed,
    });

    String id;
    String uid;
    DateTime removed;
}
final url = Uri.parse('http://ip-api.com/xml/');
final request = await httpClient.getUrl(url);
final response = await request.close();
final stream = response
    .transform(utf8.decoder)
    .transform(const XmlEventDecoder())
    .transform(const XmlNormalizer())
    .expand((events) => events)
    .forEach((event) => print(event));