如何在Flutter中对来自HttpClient流的XML元素进行分组。

问题描述 投票:0回答:1

我订阅了一个我无法控制的API,它返回一个XML结构。该结构可能非常大,如果作为一个单一的调用,需要10多秒才能返回。我有能力将其流式化(API上的一个参数),这将以块的形式返回该结构。能够在读取时处理流,将大大改善我的应用的UX。

我如何将分块的响应转化为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块,如

<c>
36
</c>

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

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

看来我需要一个 transform 方法,并能够指定 <a> 作为我的划分标签,这样子元素就会被分组,并在完成后流转。

xml flutter dart stream
1个回答
1
投票

下面的代码有点笨拙,但只用简单的操作符就能在单个流中实现你所需要的功能。

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) => ...);
© www.soinside.com 2019 - 2024. All rights reserved.