XMLStarlet:根据位置索引连接来自不同父节点的节点值

XMLStarlet: concatenate node values from different parents based on positional index

我正在尝试解析 XML 文件并生成特定值的 CSV。这是一个示例 XML 文件: http://forecast.weather.gov/MapClick.php?lat=31.7815&lon=-84.3711&FcstType=digitalDWML

XML 文件有两种我感兴趣的不同节点类型。

  1. start-valid-time 个节点(//start-valid-time
  2. value 个节点的 coverage 属性没有 additional 属性 (//weather-conditions/value[not(@additive)]/@coverage)。

节点不是通过嵌套而是通过位置链接在一起的。 第一个 start-valid-time 节点对应于第一个 //weather-conditions/value[not@additive)]/@coverage 属性。

我想输出 start-valid-time 后跟逗号后跟相应的 coverage 属性。 例如

2015-03-11T14:00:00-04:00, chance 2015-03-11T15:00:00-04:00, chance ... 2015-03-12T03:00:00-04:00, slight chance

我尝试了各种 xmlstarlet 命令都无济于事。

这是一个:

xmlstarlet sel -T  -t -m "//weather-conditions/value[not(@additive)]" -v "//start-valid-time" -v "@coverage" -n  XML 

也许我最接近这个命令:

xmlstarlet sel -T  -t -m "//start-valid-time" -v "concat(current(),',',//weather-conditions[count(preceding-sibling::start-valid-time)+1]/value/@coverage)" -n XML

但是 coverage 属性的值似乎都来自它的第一个实例。

非常感谢您对此提供帮助!

仅在 XPath 中这是一个非常困难的调用,但在 XSLT 中却非常简单。

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text" encoding="UTF-8" />

  <xsl:variable name="weatherCond" select="//weather-conditions/value[not(@additive)]" />

  <xsl:template match="/">
    <xsl:for-each select="//start-valid-time">
      <xsl:variable name="myPos" select="position()" />
      <xsl:value-of select="." />
      <xsl:text>,</xsl:text>
      <xsl:value-of select="$weatherCond[position() = $myPos]/@coverage" />
      <xsl:value-of select="'&#xA;'" />
    </xsl:for-each>
  </xsl:template>
</xsl:transform>

产出

2015-03-11T17:00:00-04:00,chance
2015-03-11T18:00:00-04:00,chance
2015-03-11T19:00:00-04:00,chance
2015-03-11T20:00:00-04:00,chance
2015-03-11T21:00:00-04:00,chance
2015-03-11T22:00:00-04:00,chance
2015-03-11T23:00:00-04:00,chance
2015-03-12T00:00:00-04:00,chance
2015-03-12T01:00:00-04:00,chance
2015-03-12T02:00:00-04:00,slight chance
2015-03-12T03:00:00-04:00,slight chance
2015-03-12T04:00:00-04:00,slight chance
...

也就是说,我想您也可以简单地使用两个基本的 xmlstarlet select 命令和 join their outputs line-wise.