bash,xmlstarlet提取两个节点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bash,xmlstarlet提取两个节点相关的知识,希望对你有一定的参考价值。

所以,我正在尝试从KML文件中提取一些地理数据。我看到的一切表明我可以在bash中使用xmlstarlet。我试图从样本数据的这个(代表性)部分获取CSV文件(之前修改为单行):

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" 
     xmlns:gx="http://www.google.com/kml/ext/2.2">
  <Document>
    <Placemark>
      <open>1</open>
      <gx:Track>
        <altitudeMode>clampToGround</altitudeMode>
        <when>2015-12-24T18:20:57Z</when>
        <gx:coord>-87.2788204 36.5984675 0</gx:coord>
        <when>2015-12-24T18:20:42Z</when>
        <gx:coord>-87.2784049 36.597298699999996  0</gx:coord>
      </gx:Track>
    </Placemark>
  </Document>
</kml>

那写道:

2015-12-24 18:20:57 -87.2788204 36.5984675 0
2015-12-24 18:20:42 -87.2784049 36.597298699999996 0

经过sed(OSX Sierra)的一点处理。

使用以下内容,我可以提取“gx:coord”节点,但同样不适用于“when”节点(为什么?):

xmlstarlet sel -t -m '//gx:coord' -v . -n <in.kml > out.csv

在尝试将多个sed迭代的基本解决方案拼凑在一起之后,我回到了这个解决方案,它将始终如一地工作,干净利落地产生最佳结果(xmlstarlet产生“when”和“gx:coord”数据......我我不熟悉XLST。关于实现这一目标的命令或步骤的建议?谢谢!

答案

这是因为when在默认命名空间http://www.opengis.net/kml/2.2中。

尝试将前缀绑定到命名空间(使用-N)。

例...

xmlstarlet sel -N kml='http://www.opengis.net/kml/2.2' -t -m '//gx:coord' -v "concat(preceding-sibling::kml:when[1],' ',.)" -n in.kml

输出...

2015-12-24T18:20:57Z -87.2788204 36.5984675 0
2015-12-24T18:20:42Z -87.2784049 36.597298699999996  0

我刚注意到你也试图在when上做一些字符串操作。它可能在命令行上变得丑陋,所以我更喜欢XSLT,但这里有一个选项......

xmlstarlet sel -N kml='http://www.opengis.net/kml/2.2' -t -m '//gx:coord' -v "concat(translate(preceding-sibling::kml:when[1],'TZ','  '),.)" -n in.kml

输出...

2015-12-24 18:20:57 -87.2788204 36.5984675 0
2015-12-24 18:20:42 -87.2784049 36.597298699999996  0

以上是关于bash,xmlstarlet提取两个节点的主要内容,如果未能解决你的问题,请参考以下文章

为啥 xmlstarlet 不选择所有节点?

在 plist 文件中如何通过 xmlstarlet 工具在唯一键标记后提取字符串文本

info.plist - xmlstarlet 不返回指定节点

脚本在Windows中运行但在Jenkins中失败

sh Bash的代码片段

xmlstarlet 默认命名空间