XMLStarlet: Printing one line per item, while using datum from parent element
Search for the WaveformData -- given as it's what you want one line per each of -- and just traverse upwards in the tree to find your time element.
$ xmlstarlet sel -T -t -m /XML/Waveforms/WaveformData \ -v ../@Time -o "," \ -v @Channel -o "," \ -v . -n <in.xml01/01/2009 3:00:02 AM,I,1, 2, 3, 4, 5, 6 01/01/2009 3:00:02 AM,II,9, 8, 7, 6, 5, 4 01/01/2009 3:00:04 AM,I,1, 2, 3, 4, 5, 6 01/01/2009 3:00:04 AM,II,9, 8, 7, 6, 5, 4
Alternately, if you know that each Waveforms will have exactly two WaveformData children, you could do the following:
$ xmlstarlet sel -T -t -m /XML/Waveforms \ -v ./@Time -o ",I," -v './WaveformData[@Channel="I"]' -n \ -v ./@Time -o ",II," -v './WaveformData[@Channel="II"]' -n <in.xml01/01/2009 3:00:02 AM,I,1, 2, 3, 4, 5, 601/01/2009 3:00:02 AM,II,9, 8, 7, 6, 5, 401/01/2009 3:00:04 AM,I,1, 2, 3, 4, 5, 601/01/2009 3:00:04 AM,II,9, 8, 7, 6, 5, 4
To give a slight variation of Charles Duffy's answer, you could use the concat()
function to simplify it a bit, and an initial template to provide the CSV header:
$ xmlstarlet sel \ -t -o 'Time Attribute, Channel Attribute, Data' -n \ -t -m '//Waveforms/WaveformData' \ -v 'concat(../@Time, ", ", @Channel, ", ", text())' -n \ waveforms.xmlTime Attribute, Channel Attribute, Data01/01/2009 3:00:02 AM, I, 1, 2, 3, 4, 5, 601/01/2009 3:00:02 AM, II, 9, 8, 7, 6, 5, 401/01/2009 3:00:04 AM, I, 1, 2, 3, 4, 5, 601/01/2009 3:00:04 AM, II, 9, 8, 7, 6, 5, 4