XMLStarlet:每个项目打印一行,同时使用来自父元素的数据
XMLStarlet: Printing one line per item, while using datum from parent element
我有 XML 数据以这种方式格式化:
<XML>
<Waveforms Time="01/01/2009 3:00:02 AM">
<WaveformData Channel="I">1, 2, 3, 4, 5, 6 </WaveformData>
<WaveformData Channel="II">9, 8, 7, 6, 5, 4 </WaveformData>
</Waveforms>
<Waveforms Time="01/01/2009 3:00:04 AM">
<WaveformData Channel="I">1, 2, 3, 4, 5, 6 </WaveformData>
<WaveformData Channel="II">9, 8, 7, 6, 5, 4 </WaveformData>
</Waveforms>
</XML>
我正在尝试使用 xmlstarlet 将此数据解析为文本文件(以逗号分隔)。所需的输出如下所示:
Time Attribute, Channel Attribute, Data
01/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:02 AM, I, 1, 2, 3, 4, 5, 6
01/01/2009 3:00:02 AM, II, 9, 8, 7, 6, 5, 4
我能想到的最好的是:
xmlstarlet sel -T -t -m //XML/Waveforms -v @Time -o "," -m Waves -v WaveformData/@Channel -o "," -v WaveformData -o "," -b -n testwave2.xml > testwave.txt
结果如下:
01/01/2009 3:00:02 AM, I, 1, 2, 3, 4, 5, 6, II, 9, 8, 7, 6, 5, 4
01/01/2009 3:00:04 AM, I, 1, 2, 3, 4, 5, 6, II, 9, 8, 7, 6, 5, 4
很清楚如何为每个 Waveforms 打印一行,但不清楚如何为每个 WaveformData 打印一行如果我想包含其父项的时间属性。这可以做到吗?或者,我是否应该变通并进行一些切片和粘贴以在之后将其修复到后端?
搜索 WaveformData——因为它是你想要的,每行一行——然后在树中向上遍历以找到你的时间元素。
$ xmlstarlet sel -T -t -m /XML/Waveforms/WaveformData \
-v ../@Time -o "," \
-v @Channel -o "," \
-v . -n <in.xml
01/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
或者,如果您知道每个 Waveforms 将恰好有两个 WaveformData 子项,您可以执行以下操作:
$ 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.xml
01/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
为了对 Charles Duffy 的回答稍作修改,您可以使用 concat()
函数稍微简化它,并使用初始模板来提供 CSV header:
$ xmlstarlet sel \
-t -o 'Time Attribute, Channel Attribute, Data' -n \
-t -m '//Waveforms/WaveformData' \
-v 'concat(../@Time, ", ", @Channel, ", ", text())' -n \
waveforms.xml
Time Attribute, Channel Attribute, Data
01/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
我有 XML 数据以这种方式格式化:
<XML>
<Waveforms Time="01/01/2009 3:00:02 AM">
<WaveformData Channel="I">1, 2, 3, 4, 5, 6 </WaveformData>
<WaveformData Channel="II">9, 8, 7, 6, 5, 4 </WaveformData>
</Waveforms>
<Waveforms Time="01/01/2009 3:00:04 AM">
<WaveformData Channel="I">1, 2, 3, 4, 5, 6 </WaveformData>
<WaveformData Channel="II">9, 8, 7, 6, 5, 4 </WaveformData>
</Waveforms>
</XML>
我正在尝试使用 xmlstarlet 将此数据解析为文本文件(以逗号分隔)。所需的输出如下所示:
Time Attribute, Channel Attribute, Data
01/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:02 AM, I, 1, 2, 3, 4, 5, 6
01/01/2009 3:00:02 AM, II, 9, 8, 7, 6, 5, 4
我能想到的最好的是:
xmlstarlet sel -T -t -m //XML/Waveforms -v @Time -o "," -m Waves -v WaveformData/@Channel -o "," -v WaveformData -o "," -b -n testwave2.xml > testwave.txt
结果如下:
01/01/2009 3:00:02 AM, I, 1, 2, 3, 4, 5, 6, II, 9, 8, 7, 6, 5, 4
01/01/2009 3:00:04 AM, I, 1, 2, 3, 4, 5, 6, II, 9, 8, 7, 6, 5, 4
很清楚如何为每个 Waveforms 打印一行,但不清楚如何为每个 WaveformData 打印一行如果我想包含其父项的时间属性。这可以做到吗?或者,我是否应该变通并进行一些切片和粘贴以在之后将其修复到后端?
搜索 WaveformData——因为它是你想要的,每行一行——然后在树中向上遍历以找到你的时间元素。
$ xmlstarlet sel -T -t -m /XML/Waveforms/WaveformData \
-v ../@Time -o "," \
-v @Channel -o "," \
-v . -n <in.xml
01/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
或者,如果您知道每个 Waveforms 将恰好有两个 WaveformData 子项,您可以执行以下操作:
$ 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.xml
01/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
为了对 Charles Duffy 的回答稍作修改,您可以使用 concat()
函数稍微简化它,并使用初始模板来提供 CSV header:
$ xmlstarlet sel \
-t -o 'Time Attribute, Channel Attribute, Data' -n \
-t -m '//Waveforms/WaveformData' \
-v 'concat(../@Time, ", ", @Channel, ", ", text())' -n \
waveforms.xml
Time Attribute, Channel Attribute, Data
01/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