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

时间:2015-03-11 20:20:43

标签: xml csv xslt xmlstarlet

我正在尝试解析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. 没有coverage属性(value)的additional个节点的//weather-conditions/value[not(@additive)]/@coverage属性。
  3. 节点不是通过嵌套而是通过位置链接在一起。 第一个start-valid-time节点对应于第一个//weather-conditions/value[not@additive)]/@coverage属性。

    我想输出start-valid-time后跟逗号,后跟相应的coverage属性。 e.g

    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属性的值似乎都来自它的第一个实例。

    我很感激这个帮助!

1 个答案:

答案 0 :(得分:2)

仅在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选择命令和join their outputs line-wise