如何在Flutter中对来自HttpClient流的XML元素进行分组 [英] How to group XML elements from a HttpClient stream in Flutter

查看:96
本文介绍了如何在Flutter中对来自HttpClient流的XML元素进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我订阅了一个我无法控制的API,该API返回XML结构。该结构可能非常大,如果作为一次调用被拉回,则需要10秒钟以上的时间才能返回。我可以流式传输它(API上的一个参数),它将以块的形式返回结构。能够在读取流时对其进行处理将大大改善我的应用的用户体验。

I subscribe to an API over which I have no control which returns an XML structure. That structure can be really big and take 10+ seconds to return if pulled as a single call. I have the ability to stream it (a parameter on the API) which will return the structure in chunks. Being able to process the stream as it is read will greatly improve my app's UX.

如何将块的响应转换为XML块?

How do I transform the response of chunks into blocks of XML?

    final url = Uri.parse(uri);
    final request = await HttpClient().getUrl(url);
    final response = await request.close();
    final stream = response
        .transform(utf8.decoder)         
        .transform(const xml_events.XmlEventDecoder())
        .transform(const xml_events.XmlNormalizer())
        .expand((events) => events)        
        .forEach((event) => log.info('Stream Receipt: $event'));
    }

这将向我返回格式良好的XML的各个块,例如

This will return me the individual blocks of well-formed XML such as

<c>
36
</c>

但是我真正需要的是构成对象的块,例如

but what I really need is for the blocks that make an object, such as

<a id="1">
<b name="Joe">
<c>36</c>
</b>
</a>

似乎我需要一个 transform 方法并可以指定< a> 作为我的轮廓标记,以便子元素在完成时进行分组和流式传输?

It seems like I need a transform method and be able to specify <a> as my delineation tag so that the child elements are grouped and streamed when complete?

推荐答案

以下代码有点尴尬,但是仅使用简单的运算符就可以在单个流中完成所需的操作:

The following code is a bit awkward, but does what you need in a single stream using only simple operators:

input
    .transform(const XmlEventDecoder())
    .transform(const XmlNormalizer())
    .expand((events) => events)
    // skip to the start of the container
    .skipWhile((event) => !(event is XmlStartElementEvent && event.name == 'root'))
    // skip over the container element
    .skip(1)
    // consume until the end of the container
    .takeWhile((event) => !(event is XmlEndElementEvent && event.name == 'root'))
    // create a forest of sub-trees
    .map((event) => [event])
    .transform(const XmlNodeDecoder())
    .expand((elements) => elements)
    // filter out the text elements between the sub-trees
    .where((element) => element is XmlElement)
    // do something with the sub-trees
    .listen((element) => ...);

这篇关于如何在Flutter中对来自HttpClient流的XML元素进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆