The XML::Writer <https://github.com/masak/xml-writer> module side-steps any ordering issues by directly serializing data structures to xml:
$ raku -M XML::Writer -e'say XML::Writer.serialize: :wpt[ :lat<42>, :long<69>, "blah" ]' <wpt lat="42" long="69">blah</wpt> On Sat, Jul 17, 2021 at 4:48 AM Bruce Gray <robertbrucegr...@gmail.com> wrote: > > On Jul 15, 2021, at 11:02 PM, William Michels via perl6-users < > perl6-us...@perl.org> wrote: > > (and I re-ordered): > > > Any help appreciated, > > Thanks, Bill. > > REFERENCE: https://unix.stackexchange.com/q/166675/227738 > > > > I'm trying to put an answer together for SO, and I keep running into the > same difficulty. Given a CSV file, > > Note: input is a log file, not in CSV format. > > > how can one produce an XML file with latitude and longitude values > properly quoted? Every time I get proper quoting, "lat" and "lon" are > scrambled (i.e. sometimes "lat" first, sometimes "lat" second). > ... > > using the "make-xml()" function from the XML module, I end up scrambling > "lat/lon”: > > You are using the correct XML module, and you are using it correctly. > > Similar to a Raku hash, the attributes in an XML start-tag are *unordered*. > While the inconsistant ordering may be displeasing to our human eyes, any > program reading XML should treat your current output identically to your > desired output. > > In Raku-speak, these two hashes have the same contents: > my %wpt1 = lat => 'A', lon => 'z'; > my %wpt2 = lon => 'z', lat => 'A’; > > Designers of XML libraries are reluctant to add the ability to force an > ordering; it would lead to XML-reading programs making improper assumptions. > Like many major XML libraries in other languages, I see no such ability in > the Raku XML module. > See: > https://www.w3.org/TR/REC-xml/#sec-starttags > Note that the order of attribute specifications > in a start-tag or empty-element tag is not significant. > > https://stackoverflow.com/questions/57756005/writing-xml-attributes-and-namespace-declarations-in-a-specific-order > > https://community.adobe.com/t5/coldfusion/maintain-attribute-order-in-xml-with-a-structure/m-p/3838398 > > > Conversely, if I manage to restrict "lat/lon" to the correct order, I > lose the equals sign and proper (value) quotation. > > > Unless you just hardcode a template and insert the lat/lon/datetime values > (never a good idea), you will have to live with the varying order. > I will point out that the XML library also does not output the multi-line > indentation that the OP shows; it is irrelevant in XML. > > > > $ raku -MXML -e 'my @xml = do for lines() {make-xml("wpt", > :lat(.words[5].subst(";")), :lon(.words[8]), \("time",.words[0..2]))}; .put > for @xml;’ lat_lon.txt > > Minor critiques: > That use of `@array = do for lines() {…}` is more commonly written as > `@array = lines().map: {…}` > raku -MXML -e 'my @xml = lines().map: {make-xml("wpt", > :lat(.words[5].subst(";")), :lon(.words[8]), \("time",.words[0..2]))}; .put > for @xml;' lat_lon.txt > > Nothing is gained by creating an array, just to print each line of the > array, so your can just `put` each time you construct an XML line. > raku -MXML -e 'for lines() { put make-xml("wpt", > :lat(.words[5].subst(";")), :lon(.words[8]), \("time",.words[0..2])) }' > lat_lon.txt > > When all the output is per-line based on the input, the `-p` or `-n` flag > removes the need for `for lines`. > raku -MXML -ne 'put make-xml("wpt", :lat(.words[5].subst(";")), > :lon(.words[8]), \("time",.words[0..2]))' lat_lon.txt > > > > > So far, I can correctly swap the date/time to the end: > > > > $ raku -MXML -e 'my @reordered = do for lines() > {(.words[3..*],.words[0..2])}; .put for @reordered;’ lat_lon.txt > > I am sure that `-MXML` is leftover from other experiments. > Removing `@reordered` and switching to `-n` like my critiques above, this > becomes: > raku -ne 'put (.words[3..*],.words[0..2]);' lat_lon.txt > To “wow” the SO crowd, you might note that @array[N..*],@array[0..N-1] has > a shortcut in Raku (.rotate), making this the tightest of all the solutions > I see so far: > raku -ne 'put .words.rotate(3);' lat_lon.txt > > -- > Hope this helps, > Bruce Gray (Util of PerlMonks) > >