我正在使用xmlstarlet
从具有特定前置兄弟事件的元素中提取文本。来自 XML 文件的示例:
<event type='cue' units='sec'>
<onset>11.134</onset>
<duration>0.2</duration>
<value name='side'>CUER</value>
</event>
<event type='target' units='sec'>
<onset>11.367</onset>
<duration>1.26</duration>
<value name='side'>TARGETR</value>
<value name='RT' units='msec'>379</value>
<value name='TargCorr'>1</value>
<value name='feedback'>YOU WIN!</value>
</event>
<event type='anticipation' units='sec'>
<onset>12.651</onset>
<duration>2.65</duration>
<value name='TargCorr'>1</value>
<value name='feedback'>YOU WIN!</value>
</event>
从示例中,我需要执行以下操作:
- 打印的
onset
,<event type='target'
和 duration
打印的<event type='target'
和紧随duration
其后的总和<event type='anticipation'
。
onset
我可以使用选项打印正确的"preceding-sibling"
:
xmlstarlet sel -t \
-m '//event[@type="anticipation" and value[@name="feedback"]="YOU WIN!"]' \
-m 'preceding-sibling::event[@type="target" and value[@name="feedback"]="YOU WIN!"][1] ' \
-v 'onset' -o ' ' -v 'duration' -o ' ' -o '1' -n $DIR/$xml \
> $DIR/output.stf
尽管如上所写,但以下代码仅显示匹配元素的持续时间,而不是两个相邻事件的持续时间之和。后者可以使用 xmlstarlet 吗?
感谢您的帮助!
我在回答时没有仔细查看您提供的代码,因为它与前面的描述不符。
假设您想要检索
onset
每个event
节点的值,其type
属性的值为target
,您可以使用xmlstarlet
with另一种写法是匹配所需的节点集并依次
onset
从每个节点中提取值。这实际上引入了一种在移动到下一个匹配节点之前在单个节点上执行多个操作的方法。“后续兄弟节点”与选择器一起使用,我们使用获得具有值的属性
following-sibling
的第一个后续event
兄弟节点。type
anticipation
following-sibling::event[@type = "anticipation"][1]
将匹配节点及其兄弟节点的值相加
duration
是通过 完成的sum()
,我们将其与上面的命令结合起来,如下所示:或者,使用短选项,
请注意为函数创建节点集的语法
sum()
。将求和的节点集与任一|
-delimited XPath 查询相匹配。鉴于问题中的示例数据,添加了一些封装根节点,这将输出
...其中第一个数字是
onset
来自节点的数字,第二个是节点和关联兄弟节点的值target
的总和。duration
target
anticipation