【问题标题】:CSV to Specific XML with Powershell使用 Powershell 将 CSV 转换为特定的 XML
【发布时间】:2012-03-07 19:33:53
【问题描述】:

我正在尝试使用 powershell 将 csv 转换为 xml 表。有没有一种方法可以准确地指定 xml 将输出的内容。

Example CSV input: 
TIME,TEMP,HUMID,DEWPT
"03/07/2012 12:04:59",72.1,73.2,62.5
"03/07/2012 11:34:53",71.9,73.8,62.5
"03/07/2012 11:04:46",71.8,74.6,62.7
"03/07/2012 10:34:39",72.3,72.6,62.4
"03/07/2012 10:04:33",71.9,72.1,61.9

Example XML output:
<?xml version="1.0" encoding="UTF-8" ?> 
- <chart>
- <series>
  <value xid="0">03/07/2012 00:02:06</value> 
  <value xid="1">03/07/2012 00:32:17</value> 
  <value xid="2">03/07/2012 01:02:26</value> 
  <value xid="3">03/07/2012 01:32:35</value> 
  <value xid="4">03/07/2012 02:02:42</value>
  </series>
- <graphs>
- <graph gid="0" color="#32CD32" axis="right" title="Temperature">
  <value xid="0">43.1</value> 
  <value xid="1">44.0</value> 
  <value xid="2">43.6</value> 
  <value xid="3">43.1</value> 
  <value xid="4">42.7</value> 
  </graph>
- <graph gid="1" color="#FFD700" axis="left" title="Humidity">
  <value xid="0">64.6</value> 
  <value xid="1">100.0</value> 
  <value xid="2">57.7</value> 
  <value xid="3">71.6</value> 
  <value xid="4">44.3</value> 
  </graph>
  <graph gid="2" color="#8B008B" axis="left" title="Dewpoint">
  <value xid="0">30.4</value>
  <value xid="1">44</value>
  <value xid="2">28.4</value>
  <value xid="3">32.9</value>
  <value xid="4">22.6</value>
  </graph>
  </graphs>
  </chart>

数据可能不是 100% 对齐的,我没有从同一个地方抓取每个样本,但你应该得到偏差。这样的事情可能吗?

另外...我维护一个大型的 master-csv。每小时添加两条记录。是否可以像那样巧妙地使 csv-to-xml 增量,或者我每次都必须针对 master-csv 运行脚本。我知道它会在 master-csv 上运行,但我担心随着时间的推移,随着列表的不断增长,它需要的时间会越来越长。如果我能够只添加新条目,那会更快。

【问题讨论】:

    标签: xml powershell csv


    【解决方案1】:

    这行得通吗?

     $head = @'
     <?xml version="1.0" encoding="UTF-8" ?> 
     <chart>
     <series>
     '@
    
     $series = @'
     '@
    
     $temp_graph = @'
     </series>
     <graphs>
     <graph gid="0" color="#32CD32" axis="right" title="Temperature">
    
     '@
    
     $humid_graph = @'
     <graph gid="1" color="#FFD700" axis="left" title="Humidity">
    
     '@
    
     $dewpt_graph = @'
     <graph gid="2" color="#8B008B" axis="left" title="Dewpoint">
    
     '@
    
     $end = @'
     </graphs>
     </chart>
     '@
    
     $i = 0
    
     import-csv file.csv |
     foreach-object {
    
     $series += @"
     <value xid="$i">$($_.TIME)</value>
    
     "@
    
     $temp_graph += @"
     <value xid="$i">$($_.TEMP)</value>
    
     "@
    
     $humid_graph += @"
     <value xid="$i">$($_.HUMID)</value>
    
     "@
    
     $dewpt_graph += @"
     <value xid="$i">$($_.DEWPT)</value>
    
     "@
    
     $i++
     }
     $temp_graph,$humid_graph,$dewpt_graph | foreach {$_ += '<\graph>'
     $head + $series + $temp_graph + $humid_graph + $dewpt_graph + $end
    

    【讨论】:

    • 我在尝试此代码时遇到错误:字符串开始:在 line:1 char:9 + $head =
    • 复制/过去错误。终止的 '@ 和 "@ 必须是该行的开头。
    • 你是对的。一旦我解决了这个问题,它就可以正常工作了。感谢您的帮助。
    • 好吧,我发现了另一个问题。 Temp 和 Humid 上没有结束 标记。我尝试将它们添加到脚本中并得到奇怪的格式。我试图在下一节的开头添加它。
    • 我用原始脚本进行了更多测试,它在一台机器上运行,在另一台机器上出现问题。它遇到的问题是旧版本的powershell。这会有所作为吗?此外,您发布的新脚本。在任何一台机器上都没有任何运气,添加 。但即使它没有添加它在开始时仍然存在问题。打算在星期一重温这个。可能必须使用具有早期版本的 powershell 的机器。
    【解决方案2】:

    以下脚本以增量方式将数据添加到 xml(使用正则表达式和替换功能)。 csv 文件input.csv 应该只包含新条目。

    # filename: test.ps1
    
    function Get-ScriptDirectory
    {
    
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value
    Split-Path $Invocation.MyCommand.Path
    }
    $csvpath = join-path (get-scriptdirectory) input.csv
    $xmlpath = join-path (get-scriptdirectory) output.xml
    
    if (!(test-path $xmlpath)) {
      @"
      <?xml version="1.0" encoding="UTF-8" ?> 
      <chart>
      <series>
      </series>
      <graphs>
      <graph gid="0" color="#32CD32" axis="right" title="Temperature">
      </graph>
      <graph gid="1" color="#FFD700" axis="left" title="Humidity">
      </graph>
      <graph gid="2" color="#8B008B" axis="left" title="Dewpoint">
      </graph>
      </graphs>
      </chart>
    "@ | out-file -encoding "UTF8" $xmlpath
    }
    
    $xml = [System.IO.File]::ReadAllText($xmlpath)
    
    
    
    $data = import-csv $csvpath
    
    $counter = [int](([regex]‘xid="(\d*)"’).matches($xml) | foreach {$_.Groups[1].Value} | %{[int] $_} | sort | select -last 1)
    $series = $null;$temp_graph = $null;$humid_graph = $null;$dewpt_graph = $null
    
    $data | %{
    $counter++
    $series += @"
     <value xid="$counter">$($_.TIME)</value>
    
    "@
    
     $temp_graph += @"
     <value xid="$counter">$($_.TEMP)</value>
    
    "@
    
     $humid_graph += @"
     <value xid="$counter">$($_.HUMID)</value>
    
    "@
    
     $dewpt_graph += @"
     <value xid="$counter">$($_.DEWPT)</value>
    
    "@
    }
    $xml = $xml -replace "</series>","$series</series>"
    $xml = $xml -replace "</graph>\r*\n*\s*<graph gid=`"1`"","$temp_graph</graph><graph gid=`"1`""
    $xml = $xml -replace "</graph>\r*\n*\s*<graph gid=`"2`"","$humid_graph</graph><graph gid=`"2`""
    $xml = $xml -replace "</graph>\r*\n*\s*</graphs>","$dewpt_graph</graph></graphs>"
    
    $xml | out-file -encoding "UTF8" $xmlpath
    

    【讨论】:

    • 这种工作。它逐步添加了时间和露点条目,但湿度和温度没有更新。
    猜你喜欢
    • 2017-09-09
    • 2021-02-17
    • 2014-12-29
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 2015-08-23
    相关资源
    最近更新 更多