-
Notifications
You must be signed in to change notification settings - Fork 5
Use Case: Reading a Record List
do- edited this page Dec 25, 2021
·
34 revisions
Consider the following XML:
<Data>
<Record>
<Id>1</Id>
<Name>John Doe</Name>
</Record>
<!-- ... millions of records, same structure ...-->
</Data>The main goal is to transfrorm xmlSource, a readable utf8 bytes stream representing the input xml, into records: a stream of objects like
//...
{
Id: "1",
Name: "John Doe",
}
//...const {XMLReader, XMLNode} = require ('xml-toolkit')
const records = new XMLReader ({
filterElements : 'Record',
map : XMLNode.toObject ({})
}).process (xmlSource)
// await someLoader.load (records)Here:
- an XMLReader is created;
- with the
filterElementsthat tells him to only handleRecordelements (skipping the rootDatanode); - and the
mapoption requiring the XMLNode.toObject transformation;
- with the
- the
processmethod implicitly creates an XMLLexer instance, performs all the necessary piping and produces the desired object mode readable stream.
With XMLNode.toObject's getName option. For example, by setting
map: XMLNode.toObject ({
getName: s => s.toLowerCase (),
//...
},
we'll obtain {id: "1", name: "John Doe"} instead of {Id: "1", Name: "John Doe"}.
In general, this is what Transform streams are for.
But in simple cases, using XMLNode.toObject's map option is more handy. For example, by setting
map: XMLNode.toObject ({
map: r => {...r, ord: ++ord}
//...
},
we'll add the record counter named ord:
{Id: "1", Name: "John Doe", ord: 1},`
{Id: "989", Name: "Mary Sue", ord: 2},`
...Simple: all XML content is presented as primitive js strings except for empty strings that are mapped to null.
In most cases, that works fine for further load to database in ETL scenarios.
If you need Numbers, Dates etc, transform the output (see above).