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

XMLStarlet:基于位置索引连接来自不同父节点的节点值,xml,csv,xslt,xmlstarlet,Xml,Csv,Xslt,Xmlstarlet,我试图解析XML文件并生成特定值的CSV。下面是一个示例XML文件: XML文件有两种我感兴趣的不同节点类型 开始有效时间节点(//开始有效时间) value节点的coverage属性,这些节点没有附加的属性(//天气条件/value[非(@additional)]/@coverage) 节点不是通过嵌套而是通过位置链接在一起。 第一个开始有效时间节点对应于第一个//天气条件/值[not@additive)]/@覆盖率属性 我想输出开始有效时间,后跟一个逗号,后跟相应的覆盖率属性。 e、 g

我试图解析XML文件并生成特定值的CSV。下面是一个示例XML文件:

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

  • 开始有效时间
    节点(
    //开始有效时间
  • value
    节点的
    coverage
    属性,这些节点没有
    附加的
    属性(
    //天气条件/value[非(@additional)]/@coverage
  • 节点不是通过嵌套而是通过位置链接在一起。 第一个
    开始有效时间
    节点对应于第一个
    //天气条件/值[not@additive)]/@覆盖率
    属性

    我想输出
    开始有效时间
    ,后跟一个逗号,后跟相应的
    覆盖率
    属性。 e、 g

    
    2015-03-11T14:00:00-04:00,机会号
    2015-03-11T15:00:00-04:00,机会号
    ...
    2015-03-12T03:00:00-04:00,机会不大
    

    我一直在尝试各种
    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 ... 2015-03-11T17:00:00-04:00,机会号 2015-03-11T18:00:00-04:00,机会号 2015-03-11T19:00:00-04:00,机会号 2015-03-11T20:00:00-04:00,机会号 2015-03-11T21:00:00-04:00,机会号 2015-03-11T22:00:00-04:00,机会号 2015-03-11T23:00:00-04:00,机会号 2015-03-12T00:00:00-04:00,机会 2015-03-12T01:00:00-04:00,机会号 2015-03-12T02:00:00-04:00,机会不大 2015-03-12T03:00:00-04:00,机会不大 2015-03-12T04:00:00-04:00,机会不大 ...
    也就是说,我想您也可以简单地使用两个基本的xmlstarlet select命令和。

    如果我没有弄错的话,该链接将毫无用处。奇怪的是,它在一秒钟前就起作用了。我更新了它。。现在它又起作用了。这太棒了。如何将@coverage更改为concat两个值节点(如果存在包含加法参数的节点)?如果每个值只能有一个加法参数,只需使用
    检查它,然后在
    if
    中使用
    输出它。如果还有更多,事情就会变得更复杂一些。等效的xmlstarlet命令应该是
    xmlstarlet sel-T-T--var'weatherCond=//天气条件/value[not(@additional)]'-m//开始有效时间--var'myPos=position()'-v-o,-v'$weatherCond[position()=$myPos]/@coverage'-n
    ,如果使用
    cmd.exe
    @npostavs,我没有意识到
    $weatherCond[position()=$myPos]
    是我需要的,而不是
    $weatherCond[position()]
    。我觉得您需要存储临时变量。谢谢!