为什么我的 XMLStarlet 查询在包含引号时不起作用?
Why doesn't my XMLStarlet query work when it includes quotes?
我有这个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 的数据集的行数。我使用的 xmlstarlet 命令是:
xmlstarlet sel -t -v 'count(/Result/Dataset[@name='ident1']/Row)' oscar.xml
我认为它应该可以工作,但它是 returning 0。
我尝试过其他变体,但都是 return 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 这样的其他元素,它 return 是正确的 4.
xmlstarlet sel -t -v 'count(/Result/Dataset)' oscar.xml
这里,引号都是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
将是根据未引用的扩展规则扩展(字符串拆分和通配导致经常不需要的行为)。
我有这个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 的数据集的行数。我使用的 xmlstarlet 命令是:
xmlstarlet sel -t -v 'count(/Result/Dataset[@name='ident1']/Row)' oscar.xml
我认为它应该可以工作,但它是 returning 0。
我尝试过其他变体,但都是 return 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 这样的其他元素,它 return 是正确的 4.
xmlstarlet sel -t -v 'count(/Result/Dataset)' oscar.xml
这里,引号都是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
将是根据未引用的扩展规则扩展(字符串拆分和通配导致经常不需要的行为)。