【发布时间】:2020-05-12 00:45:03
【问题描述】:
我订阅了一个我无法控制的 API,它返回一个 XML 结构。该结构可能非常大,如果作为单个调用拉出,则需要 10 多秒才能返回。我有能力流式传输它(API 上的一个参数),它将以块的形式返回结构。能够在读取流时对其进行处理将大大改善我的应用的用户体验。
如何将块的响应转换为 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> 作为我的描述标签,以便子元素在完成时进行分组和流式传输?
【问题讨论】:
-
你需要
XmlNodeCodec,像这样:Stream.value('<root><c>c1</c><c>c2</c><c>c3</c></root>') .transform(XmlEventCodec().decoder.fuse(XmlNodeCodec().decoder)) .listen((nodes) { print(nodes); nodes.forEach((node) { node.children.forEach(print); }); }); -
我看到这创建了一个新的流 1 子级深度以从
中拉出 节点。我将如何深入 2 个子级别,以便从 <root><a><b></b><c>c1</c><c>c2</c><c>c3</c></a></root>拉出<c>元素?我是否只需要知道它是第 n 个孩子,还是我可以指定某种过滤器仅将<c>元素拉入流中以收听?有没有关于转换、解码器、保险丝等的体面文档?我找到了 Flutter/Dart 文档,但它们有点简洁,没有真正的例子可言。