![xmlstarlet 中两个兄弟姐妹的总和值?](https://linux22.com/image/216948/xmlstarlet%20%E4%B8%AD%E4%B8%A4%E4%B8%AA%E5%85%84%E5%BC%9F%E5%A7%90%E5%A6%B9%E7%9A%84%E6%80%BB%E5%92%8C%E5%80%BC%EF%BC%9F.png)
我用来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 吗?
感谢您的帮助!
答案1
我没有仔细看就回答了代码您提供的内容,因为它与前面的描述不符。
假设您想要检索属性为 valueonset
的每个event
节点的值,您可以使用with来实现type
target
xmlstarlet
xmlstarlet select --template \
--value-of '//event[@type = "target"]/onset' \
-nl file
另一种编写方法是匹配所需的节点集并onset
依次从每个节点中提取值。实际上,这引入了一种在移动到下一个匹配节点之前在单个节点上执行多个操作的方法。
xmlstarlet select --template \
--match '//event[@type = "target"]' \
--value-of 'onset' \
-nl file
“后续同级节点”由选择器提供,我们使用获得其属性值的后续同级following-sibling
中的第一个。event
type
anticipation
following-sibling::event[@type = "anticipation"][1]
duration
将匹配节点及其兄弟节点的值相加是通过 完成的sum()
,我们将其与上面的命令结合起来,如下所示:
xmlstarlet select --template \
--match '//event[@type = "target"]' \
--value-of 'onset' --output ' ' \
--value-of 'sum(duration | following-sibling::event[@type = "anticipation"][1]/duration)' \
-nl file
或者,使用简短的选项,
xmlstarlet select -t \
-m '//event[@type = "target"]' \
-v 'onset' -o ' ' \
-v 'sum(duration | following-sibling::event[@type = "anticipation"][1]/duration)' \
-n file
请注意为函数创建节点集的语法sum()
。将求和的节点集与任何一个|
- 分隔的 XPath 查询相匹配。
给定问题中的示例数据,添加一些封装根节点,这将输出
11.367 3.91
...其中第一个数字是onset
来自target
节点的数字,第二个数字是duration
该target
节点和关联兄弟anticipation
节点的值之和。