我有这个XML
<Result>
<Dataset name='ident1'>
<Row name='a1'>
<queryname>cat0</queryname>
<superfilename>cat1</superfilename>
<indexfilename>cat2</indexfilename>
</Row>
<Row name='a2'>
<queryname>cat3</queryname>
<superfilename>cat4</superfilename>
<indexfilename>cat5</indexfilename>
</Row>
<Row name='a3'>
<queryname>cat6</queryname>
<superfilename>cat7</superfilename>
<indexfilename>cat8</indexfilename>
</Row>
</Dataset>
<Dataset name='Result 2'>
</Dataset>
<Dataset name='Result 3'>
</Dataset>
<Dataset name='Result 4'>
</Dataset>
</Result>
我想计算名为ident1的DataSet的行数。我使用的xmlstarlet命令是:
xmlstarlet sel -t -v 'count(/Result/Dataset[@name='ident1']/Row)' oscar.xml
我认为它应该有效,但它返回0。
我尝试了其他变体,但所有变体都返回0。
xmlstarlet sel -t -v 'count(/Result/Dataset[@name='ident1'])' oscar.xml
xmlstarlet sel -t -v 'count(/Result/Dataset[@name='ident1'][*]/Row)' oscar.xml
xmlstarlet sel -t -v 'count(/Result/Dataset[@name='ident1']/Row[*])' oscar.xml
我做错了什么?
请注意
如果我计算其他元素如DataSet,它会正确返回4。
xmlstarlet sel -t -v 'count(/Result/Dataset)' oscar.xml
答案 0 :(得分:2)
在这里,引号都是shell语法;因此,shell在向XMLStarlet提供查询之前删除了引号:
# bad: looks for @name=ident1, no quotes
# literal query is: count(/Result/Dataset[@name=ident1]/Row)
# ...which compares @name against the value of an element under Dataset named ident1
# ...since no such element exists, the result is a count of 0.
xmlstarlet sel -t -v 'count(/Result/Dataset[@name='ident1']/Row)' oscar.xml
取而代之的是:
# good: uses ""s on the outside, so ''s on the inside are literal
# literal query is: count(/Result/Dataset[@name='ident1']/Row)
xmlstarlet sel -t -v "count(/Result/Dataset[@name='ident1']/Row)" oscar.xml
...或者,如果你的shell是bash:
# good (but nonportable): uses $'' syntax, which makes \' produce a single literal '
# literal query is: count(/Result/Dataset[@name='ident1']/Row)
xmlstarlet sel -t -v $'count(/Result/Dataset[@name=\'ident1\']/Row)' oscar.xml
上述所有情况都是因为shell中的引号是每个字符的特征。例如,您可以写:
echo "$foo"'$bar'$baz
... $foo
将根据双引号规则进行扩展(文字替换为注释),$bar
将被视为文字字符串,$baz
将被展开不带引号的扩展规则(使用字符串拆分和通配符导致不需要的行为)。