使用`position()`来提取特定元素

时间:2014-03-04 18:33:57

标签: xmlstarlet

我有一个类似于

的格式的数据文件
<!-- mydata.xml -->
<alldata>
    <data id="first">
        <coord><x>0</x><y>5</y></coord>
        <coord><x>1</x><y>4</y></coord>
        <coord><x>2</x><y>3</y></coord>
    </data>
    <data id="second">
        <coord><x>0</x><y>2</y></coord>
        <coord><x>1</x><y>1</y></coord>
        <coord><x>2</x><y>0</y></coord>
    </data>
</alldata>

由于x值在xml文件的所有数据集中都相同,我想将数据提取为csv格式,如

x;first y;second y
0;5;2
1;4;1
2;3;0

天真地,我尝试在第一个<coord>元素中匹配<data>,并使用position()从下一个<y>中提取正确的<coord>带有第二个<data>属性的id元素中的s:

xml sel -T -t -m "/alldata/data[@id='first']/coord" -v "concat(x,';',y,';',../../data[@id='second']/coord[position()]/y,';',position())" -n mydata.xml

这会输出输出中所有行中第一个<y>的{​​{1}},即使<coord>在每行中递增:

position()

我如何实现我的目标?

1 个答案:

答案 0 :(得分:2)

position()给出context's position(从中调用它)。 ../../data[@id='second']/coord[position()]实际上意味着“coord下的每个data 在它自己的位置”(这是所有这些但是XPath 1.0字符串转换只需要第一个)。

要引用您正在循环的coord,可以使用XSLT函数current()。由于我现在无法想到的一些充分理由,这不适用于position(),但您可以改为count() preceding-sibling个节点:

xml sel -T -t -m "/alldata/data[@id='first']/coord" -v "concat(x,';',y,';',../../data[@id='second']/coord[count(current()/preceding-sibling::*)+1]/y)" -n mydata.xml