Reputation: 104
I am trying to access specific XML tag names from an Iterable Stream of XML Events. Is there a way as I can only find a way to print the text of each XmlEvent irrespective of tag/element name? Below my code.
Future<String> getDataFromXml() async {
String xmlString = await DefaultAssetBundle.of(context)
.loadString('assets/gpx/filename');
var events = parseEvents(xmlString).whereType<XmlTextEvent>();
Stream.fromIterable(events)
.where((event) => event is XmlEvent)
.cast<XmlEvent>()
.forEach(print);
I understand how to access the elements from a parsed XML document (which is not a stream), but not from a stream of XML events.
Upvotes: 2
Views: 766
Reputation: 985
I just added the inner text for each tag I needed to its own List:
import 'package:xml/xml.dart';
import 'package:xml/xml_events.dart';
printTagLists();
Future<void> printTagLists() async {
String xmlFileContents = "<ip>192.168.1.1</ip><mac>Mac1</mac><mac>Mac2</mac><host>hostName1</host>";
List<String> mac = <String>[];
List<String> ip = <String>[];
List<String> host = <String>[];
String tag = "";
String tagText = "";
await Stream.fromIterable([
xmlFileContents]).toXmlEvents().toXmlNodes().forEach((nodeStream) {
tag = nodeStream.toString();
tagText = nodeStream.first.innerText;
(tag.contains("<mac>")
? mac.add(tagText)
: (tag.contains("<ip>")
? ip.add(tagText)
: (tag.contains("host") ? host.add(tagText) : "")));
});
print("This is mac $mac");
print("This is ip $ip");
print("This is host $host");
}
Produces:
This is mac [Mac1, Mac2]
This is ip [192.168.1.1]
This is host [hostName1]
Note, this won't work on nested tags.
Upvotes: 0
Reputation: 8947
First of all, only XmlTextEvent
(and XmlCDATAEvent
) contain text. You can access the text by calling text
on these events.
I don't quite understand what you want to do? events
is an Iterable<XmlTextEvent>
with all the text events. Then you filter and cast that Iterable<XmlTextEvent>
with a Stream
to the superclass XmlEvent
, which doesn't do anything. Just printing events
would do the same.
Note that the package has two approaches to event-based XML parsing: the synchronous one that you are using with Iterable<XmlEvent> parseEvents(String)
and the asynchronous one that works on Dart Streams Stream<List<XmlEvent>> Stream.toXmlEvents()
. They both use the same event infrastructure, but the second one has much richer tooling. See the examples in the tutorial.
Upvotes: 1
Reputation: 7650
I advise you to avoid working with XML data. You should convert the XML data to JSON as possible as early. From this point of view, you can use the xml2json package.
final myTransformer = Xml2Json();
// Parse a simple XML string
myTransformer.parse(xmlString);
var jsonData = myTransformer.toParker();
Upvotes: 1