xmlstarlet处理纯ASCII格式XML文件查询无输出是什么原因?
问题原因
该问题和文件大小无关,核心原因是XML文件定义了默认命名空间,直接写节点名的XPath查询无法匹配到该命名空间下的节点。
你提供的XML根节点配置为 <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">,这里的xmlns属性定义了默认命名空间,该节点及其所有子节点都属于这个命名空间范围,XPath默认只会匹配无命名空间的节点,所以直接写//Key、/ListBucketResult都匹配不到任何内容。
之前的*、/*、//*能正常执行,是因为通配符匹配不会校验命名空间,只要是节点就会返回。
另外你写的/ListBucket/Result本身也是错误的路径,XML的根节点是ListBucketResult,不存在ListBucket下嵌套Result的结构,就算没有命名空间问题也无法匹配到内容。
解决方案
方案1:绑定命名空间前缀(推荐)
使用xmlstarlet的-N参数先给S3的命名空间绑定一个自定义前缀,查询时节点名前加该前缀即可:
# 提取所有Key节点的内容,每行输出一个 xmlstarlet sel -N s3="http://s3.amazonaws.com/doc/2006-03-01/" -t -v "//s3:Key" -n dl.xml # 提取完整Key节点结构 xmlstarlet sel -N s3="http://s3.amazonaws.com/doc/2006-03-01/" -t -c "//s3:Key" dl.xml
方案2:使用local-name()忽略命名空间(快速调试用)
如果不想特意绑定命名空间,可以用local-name()函数直接匹配节点名,不需要考虑命名空间:
xmlstarlet sel -t -v "//*[local-name()='Key']" -n dl.xml
该方法不推荐用于正式场景,多个命名空间下有同名节点时会出现匹配错误。
内容的提问来源于stack exchange,提问作者Thomas Schweikle
相关产品推荐
相关产品推荐

