我有一个使用XMLStarlet执行许多XML编辑操作的脚本。例如,它会删除所有foo
节点(如果存在):
xmlstarlet ed -d '//foo'
(除了在我的脚本中,元素的名称不是foo
)。
当不存在foo
节点时,将打印以下消息:
None of the XPaths matched; to match a node in the default namespace
use '_' as the prefix (see section 5.1 in the manual).
For instance, use /_:node instead of /node
但是,如果输入文档中不存在foo
节点,则没有任何错误。因此,对于这个特定的操作,我确实希望避免这个特定的警告,而我一般不想禁用此类警告。
我怎样才能做到这一点?
目前,删除不存在的节点被xmlstarlet归类为错误。返回代码将是1
,您必须将其理解为"没有删除任何节点"。
如果您碰巧使用了具有默认名称空间的文档:,则会显示错误消息
无命名空间:
echo '<foo />' | xmlstarlet sel -t -m foo -v joe
使用默认名称空间xmlstarlet打印错误消息
echo '<foo xmlns="urn:foo" />' | xmlstarlet sel -t -m foo -v joe
None of the XPaths matched; to match a node in the default namespace
use '_' as the prefix (see section 5.1 in the manual).
For instance, use /_:node instead of /node
没有默认名称空间:
echo '<ns:foo xmlns:ns="urn:foo" />' | xmlstarlet sel -t -m foo -v joe
在所有这些情况下,都找不到节点,因此xmlstarlet退出时返回代码1
(即错误)。错误消息用于解释用户忘记文档具有默认名称空间的情况下的错误。我已经和作者讨论过这一点,最近引入了一些变化,以减少这些信息的出现,并采取了一种抑制它们的方法。
xmlstarlet支持使用文档的名称空间,而无需预先声明:
比较:
echo '<ns:foo xmlns:ns="urn:foo" />' | xmlstarlet sel -t -m ns:foo -v 'count(.)'
echo '<ns:foo xmlns:ns="urn:foo" />' | xmlstarlet sel -N xx=urn:foo -t -m xx:foo -v 'count(.)'
从技术上讲,这些命令是相同的,只是第一个命令依赖于绑定到"ns"前缀的文档,而第二个命令则不依赖。
要禁止该消息,您必须将stderr重定向到null:
echo '<foo xmlns="urn:xxx"/>' |
xmlstarlet sel -t -m foo -v joe 2> /dev/null
这样做的缺点是它会抑制合法的错误消息,而不仅仅是由于源文档使用名称空间而导致的这种虚假错误消息。
在最近的版本中,添加了--no-doc-namespace
来抑制这种行为
该更改是在该变更集中引入的,并且该变更集包含关于该错误消息的长交换,所有这些都是由该StackOverflow问题引起的!