CSV zu XML Probleme mit PowerShell
Hallo,
ich habe folgendes Problem.
ich habe eine CSV Datei von einem Solar-Laderegler. Diese werte würde ich gerne in meine Haussteuerung über XML einfügen.
Jetzt habe ich durch eine Anleitung von @colinardo was schönes über Powershell gefunden.
Nur leider sind die Werte in der CSV-Datei per "," getrennt und es gibt auch kommer getrennte Messwerte in der CSV-Datei.
Hat hier vielleicht jemand eine Idee, wie ich alles in XML übertragen bekomme?
Am liebsten wäre mir hier auch nur die Ausgabe in XML des letzten wertes in der Datei
Hier der Aufbau der CSV:
Hier die Werte wie Sie Original vom Regler kommen, hier sieht man auch schön die Nachkommerstellen:
Hier der Aufbau des verwendeten Powershell Script von @colinardo
Edit:
Ich habe das Problem über ein Script auf dem Pi gelöst.
Da ich die Daten auf einem Raspberry Pi speichere.
Danke für die Hilfe!
ich habe folgendes Problem.
ich habe eine CSV Datei von einem Solar-Laderegler. Diese werte würde ich gerne in meine Haussteuerung über XML einfügen.
Jetzt habe ich durch eine Anleitung von @colinardo was schönes über Powershell gefunden.
Nur leider sind die Werte in der CSV-Datei per "," getrennt und es gibt auch kommer getrennte Messwerte in der CSV-Datei.
Hat hier vielleicht jemand eine Idee, wie ich alles in XML übertragen bekomme?
Am liebsten wäre mir hier auch nur die Ausgabe in XML des letzten wertes in der Datei
Hier der Aufbau der CSV:
Date Time,Station Name,Device ID,Array Current(A),Array Voltage(V),Array Power(W),Working State,Battery Voltage(V),Battery Temp.(?),Battery Current(A),Battery SOC(%),Load Current(A),Load Power(W),Load Voltage(V),Load State,Device Temp.(?),Battery State,Charging State,Controller Working State
2017-09-17 17:05:54,Solar,1,0,53,33,4,18,Float,27,7,20,0,67,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:06:56,Solar,1,0,53,33,4,18,Float,27,7,20,0,67,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:07:58,Solar,1,0,57,33,2,19,Float,27,7,20,0,69,100,0,29,8,27,6,1,22,No,Normal,Normal
2017-09-17 17:08:59,Solar,1,0,57,33,2,19,Float,27,7,20,0,69,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:10:01,Solar,1,0,57,33,2,19,Float,27,7,20,0,69,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:11:05,Solar,1,0,57,33,2,19,Float,27,7,20,0,69,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:12:07,Solar,1,0,57,33,2,19,Float,27,7,20,0,69,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:13:09,Solar,1,0,57,33,3,19,Float,27,7,20,0,69,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:14:10,Solar,1,0,57,33,3,19,Float,27,7,20,0,69,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:15:12,Solar,1,0,56,33,4,19,Float,27,7,20,0,71,100,0,29,8,27,6,1,22,No,Normal,Normal
2017-09-17 17:16:13,Solar,1,0,56,33,4,19,Float,27,7,20,0,69,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:17:15,Solar,1,0,56,33,4,19,Float,27,7,20,0,69,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:18:16,Solar,1,0,56,33,4,19,Float,27,7,20,0,69,100,0,30,8,26,7,1,22,No,Normal,Normal
2017-09-17 17:19:18,Solar,1,0,56,33,4,19,Float,27,7,20,0,69,100,0,29,8,27,6,1,22,No,Normal,Normal
Hier die Werte wie Sie Original vom Regler kommen, hier sieht man auch schön die Nachkommerstellen:
Hier der Aufbau des verwendeten Powershell Script von @colinardo
param(
[string]$folder,
[string]$delimiter = ","
)
# Alle CSV-Dateien des Ordners durchlaufen
gci $folder -Filter "*.csv" | %{
write-host "Konvertiere '$($_.Fullname)' ..." -ForegroundColor Green
# importiere CSV-Datei als Objekt
$csv = import-csv $_.Fullname -Delimiter $delimiter
# Spaltennamen der CSV-Datei extrahieren
$cols = $csv | gm -MemberType NoteProperty | select -ExpandProperty Name
# erzeuge neues XML-Dokument
$xml = New-Object XML
# XML Grundgerüst laden
$xml.LoadXml('<?xml version="1.0" encoding="utf-8"?><root></root>')
# Root-Knoten referenzieren
$root = $xml.SelectSingleNode("/root")
# für jede Zeile der CSV-Datei ...
foreach($line in $csv){
# erzeuge ein neues Row-Element
$row = $xml.CreateElement("row")
# für jede Spalte der Zeile erstelle ein neues Element mit dem Namen der Spalte und dem Inhalt der aktuellen Zeile
$cols | %{
$col = $xml.CreateElement($_)
$col.InnerText = $line.($_)
$row.AppendChild($col) | out-null
}
# füge das Row-Element im Root-Knoten ein
$root.AppendChild($row) | out-null
}
# Speichere die neue XML-Datei
$xml.Save($_.DirectoryName + "\" + $_.BaseName + ".xml")
}
Edit:
Ich habe das Problem über ein Script auf dem Pi gelöst.
Da ich die Daten auf einem Raspberry Pi speichere.
Danke für die Hilfe!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 349309
Url: https://administrator.de/contentid/349309
Ausgedruckt am: 23.11.2024 um 02:11 Uhr
7 Kommentare
Neuester Kommentar
Warte ... eine Datei in der das Komma sowohl Listentrennzeichen, als auch Dezimaltrennzeichen ist, kann niemals eindeutig geparst werden (zumindest nicht, wenn die Werte nicht in Anführungszeichen stehen).
Also, erst mal versuchen das Übel an der Wurzel zu packen.
Wie wird die CSV Datei erstellt?
Und hast du irgendeine Möglichkeit das Listentrennzeichen (oder alternativ das Dezimaltrennzeichen) einzustellen?
Grüße
rubberman
Also, erst mal versuchen das Übel an der Wurzel zu packen.
Wie wird die CSV Datei erstellt?
Und hast du irgendeine Möglichkeit das Listentrennzeichen (oder alternativ das Dezimaltrennzeichen) einzustellen?
Grüße
rubberman
Und die Möglichkeit, diesen Bug zu reporten, gibt's wahrscheinlich auch nicht...
Sorry, musst wohl oder übel auf die PowerSheller warten, die das Script exakt auf deine Gegebenheiten anpassen können. (Besser gesagt, neu schreiben, denn das Import-Csv Cmdlet lässt sich wohl nicht weiterhin verwenden.) Meine rudimentären Kenntnisse reichen dafür nicht.
Grüße
rubberman
Sorry, musst wohl oder übel auf die PowerSheller warten, die das Script exakt auf deine Gegebenheiten anpassen können. (Besser gesagt, neu schreiben, denn das Import-Csv Cmdlet lässt sich wohl nicht weiterhin verwenden.) Meine rudimentären Kenntnisse reichen dafür nicht.
Grüße
rubberman
Servus @comtel,
da sieht man mal wieder den Unsinn den die Jungs da bei der Entwicklung solcher Hardware zum Schluss in der Software verzapfen ...
Lässt sich aber lösen wenn die Felder immer das gleiche Dezimalformat haben, d.h. also das in den Feldern in denen es eine Kommastelle gibt diese bei jedem Wert immer ein Komma haben und die Felder mit Integerwerten später keine Nachkommastellen vorkommen, kannst das folgende von oben leicht abgeänderte Skript benutzen:
(Zeilen 7-11 ersetzen das Import-CSV des vorherigen Skripts in dem die Header-Zeile der CSV mit der letzten Zeile der CSV kombiniert wird, wobei die letzte Zeile nach Formatierungsanweisung mit Anführungszeichen versehen werden damit die PS die Spalten richtig zuordnen kann).
Der Einfachheit habe ich hier einfach mal die Methode gewählt die am wenigsten Anpassung des von dir oben geposteten Skripts erfordert.
Grüße und schönen Sonntagabend
Uwe
da sieht man mal wieder den Unsinn den die Jungs da bei der Entwicklung solcher Hardware zum Schluss in der Software verzapfen ...
Lässt sich aber lösen wenn die Felder immer das gleiche Dezimalformat haben, d.h. also das in den Feldern in denen es eine Kommastelle gibt diese bei jedem Wert immer ein Komma haben und die Felder mit Integerwerten später keine Nachkommastellen vorkommen, kannst das folgende von oben leicht abgeänderte Skript benutzen:
(Zeilen 7-11 ersetzen das Import-CSV des vorherigen Skripts in dem die Header-Zeile der CSV mit der letzten Zeile der CSV kombiniert wird, wobei die letzte Zeile nach Formatierungsanweisung mit Anführungszeichen versehen werden damit die PS die Spalten richtig zuordnen kann).
param([string]$folder)
# Alle CSV-Dateien des Ordners durchlaufen
gci $folder -Filter "*.csv" | %{
write-host "Konvertiere '$($_.Fullname)' ..." -ForegroundColor Green
# lese Datei als Zeilenarray ein
$content = gc $_.Fullname
# formatiere die letzte Zeile der Datei nach Vorgabe
$last = $content[-1] -replace '^([^,]+),([^,]+),(\d+),(\d+,\d+),(\d+,\d+),(\d+),([^,]+),(\d+,\d+),(\d+),(\d+,\d+),(\d+),(\d+,\d+),(\d+),(\d+,\d+),([^,]+),(\d+),([^,]+),([^,]+),([^,]+)$','"$1","$2","$3","$4","$5","$6","$7","$8","$9","$10","$11","$12","$13","$14","$15","$16","$17","$18","$19"'
# aus Header und modifizierter letzter Zeile ein Objekt machen
$csv = ($content,$last) | convertfrom-csv -Delimiter ","
# Spaltennamen der CSV-Datei extrahieren
$cols = $csv | gm -MemberType NoteProperty | select -ExpandProperty Name
# erzeuge neues XML-Dokument
$xml = New-Object XML
# XML Grundgerüst laden
$xml.LoadXml('<?xml version="1.0" encoding="utf-8"?><root></root>')
# Root-Knoten referenzieren
$root = $xml.SelectSingleNode("/root")
# für jede Zeile der CSV-Datei ...
foreach($line in $csv){
# erzeuge ein neues Row-Element
$row = $xml.CreateElement("row")
# für jede Spalte der Zeile erstelle ein neues Element mit dem Namen der Spalte und dem Inhalt der aktuellen Zeile
$cols | %{
$col = $xml.CreateElement($_)
$col.InnerText = $line.($_)
$row.AppendChild($col) | out-null
}
# füge das Row-Element im Root-Knoten ein
$root.AppendChild($row) | out-null
}
# Speichere die neue XML-Datei
$xml.Save($_.DirectoryName + "\" + $_.BaseName + ".xml")
}
Grüße und schönen Sonntagabend
Uwe
Zitat von @comtel:
Muss ich hier in der PowerShell Konsole Rechte zum Schreiben der Datei mit übergeben?
Nein, die CSV-Datei wird nur im Lesezugriff beaufschlagt. Was du natürlich sicherstellen musst ist das der Account unter dem das Skript ausgeführt wird, NTFS-Schreibrechte im Ordner der CSV-Datei hat, da hier auch die XML-Datei abgelegt wird.Muss ich hier in der PowerShell Konsole Rechte zum Schreiben der Datei mit übergeben?
Da die Powershell-Executionpolicy zum Ausführen von PS Skripten von dir bereits angepasst wurde, setze ich jetzt einfach mal voraus.
Wenns das dann war, den Beitrag bitte noch auf gelöst setzen, und Lösungen markieren. Merci.