PowerShell XML ergänzen-mutieren mittels Abfrage externer Daten
Seit zwei Wochen arbeite ich an PS-Scripts, die primär folgendes tun (und das tun sie bisher auch
):
1. XML-file von Web- oder FTP-Server holen
2. XML mit seinem Schema (XSD) validieren
3. XML als CSV (UTF-8) ausgeben
4. CSV mittel Aufruf eines spezifischen SQL-Import-Tools in SQL importieren
Nun steh ich vor Aufaben, die ich als PS-Neuling und Nicht-Entwickler ganz sicher nicht alleine hinbekomme! Ich hoff jetzt mal drauf, dass sich hier gute Seelen tummeln die mir dabei weiterhelfen können. Der Gesamtprozess ist ingesamt komplex und es wäre zu aufwendig hier alles wiederzugeben. Ich versuche deshalb nachfolgend zu erläutern, mit welchen Schritten/Prozessen ich meine PS-Scripts erweitern möchte.
Also, Ausgangslage ist das XML-file welches ich runterlade ... einfaches Beispiel:
Beim CSV-Output sieht das dann so aus:
Dazu folgende Erklärung:
Die drei Zeichen inkl. underline von links bei den Felder mit "...LIEF-NR" ist immer das Prefix des Datenlieferanten, welches seine interne Warengruppe reflektiert. Diese Strings inkl. dieses Prefix verwende ich direkt in der DB als "Lieferantenartikelnummer".
Der Lieferant verbiegt aufgrund der Tatsache, dass sein System im Artikelnummernfeld nur eine sehr begrenzte Anzahl an Zeichen zulässt, die ganze Logik für diese Artikelnummern. Und das ist zugleich eines der Probleme, dem ich durch eine schlaue Lösung Herr werden möchte. Das Problem was ich meine sieht man auf der zweiten Datenzeile des CSV-Outputs > der String im Feld "FATHER-LIEF-NR" ab dem underline entspricht nicht dem Wert in "FATHER-HERST-NR". Im Normalfall wäre das so, aber dort wo die "...-HERST-NR" inkl. seinem Prefix zu lang ist macht er dann irgendwas
Soweit so gut - der String in "...HERST-NR", also die Originale Hersteller-Artikelnummer, wird in meiner DB ursprünglich als meine eigene Artikelnummer importiert und verwendet. Das hat nun aber zu Doubletten geführt, weil verschiedene BRAND's (Hersteller) z.t. gleiche Artikelnummern führen! Sehr schlecht!
Meine Lösung ist nun die, dass ich jedem BRAND einen Prefix + Bindestrich zuteile; wäre beispielsweise für "Coca-Cola" ein "CCL-". Dann führe ich alle möglichen Hersteller in einer EXCEL- oder CSV Tabelle, deren erste zwei Spalten dann wie folgt ausschauen:
Und jetzt kommt das Stück PS-Script, von dem ich nicht mal ansatzweise wüsste wie das aussehen könnte!
Im SP-Script hab ich die XML-Datei mit GET-CONTENT geöffnet ...un das Ding sollte jetzt folgendes tun:
1. in der XML-Datei eine "Spalte" (Child) mit dem Namen "MY-FATHER-NR" und eine mit "MY-PART-NR" erstellen
2. die Excel/CSV-Quelle (ich nenn's mal PREFIX-DB) mit den HERSTELLER-PREFIX Definitionen für Zugriff öffnen ...
3. Bei jedem XML-Datensatz den String in "FATHER-HERST-NAME" in der PREFIX-DB suchen und dann ...
3a. in der neuen XML-Spalte "MY-ART-NO" den Prefix + Bindestrich + FATHER-HERST-NR reinschreiben.
3b. in der XML-Spalte "FATHER-HERST-NR" den Hersteller-Namen (also String aus "FATHER-HERST-NAME") + Leerschlag + FATHER-HERST-NR reinschreiben
4. Wie bei 3. aber nun beim "PART ..."
Der erste Datensatz in der XML würde dann jetzt so aussehen (bei Annahme "BRN" ist Prefix für "BRAND1":
Die ganze Darstellung ist vereinfacht - ich habe da auch XML-Files mit viel mehr Inhalt (Nodes).
Hat in diesem Universum irgend jemand eine Idee oder zumindest Ansätze wie man sowas löst?
Vielen herzlichen Dank schon mal
1. XML-file von Web- oder FTP-Server holen
2. XML mit seinem Schema (XSD) validieren
3. XML als CSV (UTF-8) ausgeben
4. CSV mittel Aufruf eines spezifischen SQL-Import-Tools in SQL importieren
Nun steh ich vor Aufaben, die ich als PS-Neuling und Nicht-Entwickler ganz sicher nicht alleine hinbekomme! Ich hoff jetzt mal drauf, dass sich hier gute Seelen tummeln die mir dabei weiterhelfen können. Der Gesamtprozess ist ingesamt komplex und es wäre zu aufwendig hier alles wiederzugeben. Ich versuche deshalb nachfolgend zu erläutern, mit welchen Schritten/Prozessen ich meine PS-Scripts erweitern möchte.
Also, Ausgangslage ist das XML-file welches ich runterlade ... einfaches Beispiel:
<?xml version="1.0" encoding="UTF-8"?>
<PRODUCTS>
<SPAREPARTS>
<FATHER-LIEF-NR>02_HRZ3100</FATHER-LIEF-NR>
<FATHER-HERST-NR>HRZ3100</FATHER-HERST-NR>
<FATHER-HERST-NAME>BRAND1</FATHER-HERST-NAME>
<PART-LIEF-NR>02_HRZ2544</PART-LIEF-NR>
<PART-HERST-NR>HRZ2544</PART-HERST-NR>
<PART-HERST-NAME>BRAND1</PART-HERST-NAME>
</SPAREPARTS>
<SPAREPARTS>
<FATHER-LIEF-NR>02_249310023</FATHER-LIEF-NR>
<FATHER-HERST-NR>949310023682021</FATHER-HERST-NR>
<FATHER-HERST-NAME>BRAND2</FATHER-HERST-NAME>
<PART-LIEF-NR>13_EFLB1303</PART-LIEF-NR>
<PART-HERST-NR>EFLB1303</PART-HERST-NR>
<PART-HERST-NAME>BRAND14</PART-HERST-NAME>
</SPAREPARTS>
<SPAREPARTS>
<FATHER-LIEF-NR>02_KZU310056</FATHER-LIEF-NR>
<FATHER-HERST-NR>KZU310056</FATHER-HERST-NR>
<FATHER-HERST-NAME>BRAND22</FATHER-HERST-NAME>
<PART-LIEF-NR>13_HRZ2274</PART-LIEF-NR>
<PART-HERST-NR>HRZ2274</PART-HERST-NR>
<PART-HERST-NAME>BRAND1</PART-HERST-NAME>
</SPAREPARTS>
... so weiter von einigen bis mehrere tausend, je nach Quelle
</PRODUCTS>
"FATHER-LIEF-NR";"FATHER-HERST-NR";"FATHER-HERST-NAME";"PART-LIEF-NR";"PART-HERST-NR";"PART-HERST-NAME"
"02_HRZ3100";"HRZ3100";"BRAND1";"02_HRZ2544";"HRZ2544";"BRAND1"
"02_249310023";"949310023682021";"BRAND2";"13_EFLB1303";"EFLB1303";"BRAND14"
"02_KZU310056";"KZU310056";"BRAND22";"13_HRZ2274";"HRZ2274";"BRAND1"
Die drei Zeichen inkl. underline von links bei den Felder mit "...LIEF-NR" ist immer das Prefix des Datenlieferanten, welches seine interne Warengruppe reflektiert. Diese Strings inkl. dieses Prefix verwende ich direkt in der DB als "Lieferantenartikelnummer".
Der Lieferant verbiegt aufgrund der Tatsache, dass sein System im Artikelnummernfeld nur eine sehr begrenzte Anzahl an Zeichen zulässt, die ganze Logik für diese Artikelnummern. Und das ist zugleich eines der Probleme, dem ich durch eine schlaue Lösung Herr werden möchte. Das Problem was ich meine sieht man auf der zweiten Datenzeile des CSV-Outputs > der String im Feld "FATHER-LIEF-NR" ab dem underline entspricht nicht dem Wert in "FATHER-HERST-NR". Im Normalfall wäre das so, aber dort wo die "...-HERST-NR" inkl. seinem Prefix zu lang ist macht er dann irgendwas
Soweit so gut - der String in "...HERST-NR", also die Originale Hersteller-Artikelnummer, wird in meiner DB ursprünglich als meine eigene Artikelnummer importiert und verwendet. Das hat nun aber zu Doubletten geführt, weil verschiedene BRAND's (Hersteller) z.t. gleiche Artikelnummern führen! Sehr schlecht!
Meine Lösung ist nun die, dass ich jedem BRAND einen Prefix + Bindestrich zuteile; wäre beispielsweise für "Coca-Cola" ein "CCL-". Dann führe ich alle möglichen Hersteller in einer EXCEL- oder CSV Tabelle, deren erste zwei Spalten dann wie folgt ausschauen:
HERSTELLERNAME | HERSTELLER-PREFIX |
Im SP-Script hab ich die XML-Datei mit GET-CONTENT geöffnet ...un das Ding sollte jetzt folgendes tun:
1. in der XML-Datei eine "Spalte" (Child) mit dem Namen "MY-FATHER-NR" und eine mit "MY-PART-NR" erstellen
2. die Excel/CSV-Quelle (ich nenn's mal PREFIX-DB) mit den HERSTELLER-PREFIX Definitionen für Zugriff öffnen ...
3. Bei jedem XML-Datensatz den String in "FATHER-HERST-NAME" in der PREFIX-DB suchen und dann ...
3a. in der neuen XML-Spalte "MY-ART-NO" den Prefix + Bindestrich + FATHER-HERST-NR reinschreiben.
3b. in der XML-Spalte "FATHER-HERST-NR" den Hersteller-Namen (also String aus "FATHER-HERST-NAME") + Leerschlag + FATHER-HERST-NR reinschreiben
4. Wie bei 3. aber nun beim "PART ..."
Der erste Datensatz in der XML würde dann jetzt so aussehen (bei Annahme "BRN" ist Prefix für "BRAND1":
<SPAREPARTS>
<MY-FATHER-NR>BRN-HRZ3100</MY-FATHER-NR>
<FATHER-LIEF-NR>02_HRZ3100</FATHER-LIEF-NR>
<FATHER-HERST-NR>BRAND1 HRZ3100</FATHER-HERST-NR>
<FATHER-HERST-NAME>BRAND1</FATHER-HERST-NAME>
<MY-PART-NR>BRN-RZ2544</MY-PART-NR>
<PART-LIEF-NR>02_HRZ2544</PART-LIEF-NR>
<PART-HERST-NR>BRAND1 HRZ2544</PART-HERST-NR>
<PART-HERST-NAME>BRAND1</PART-HERST-NAME>
</SPAREPARTS>
Hat in diesem Universum irgend jemand eine Idee oder zumindest Ansätze wie man sowas löst?
Vielen herzlichen Dank schon mal
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 438456
Url: https://administrator.de/forum/powershell-xml-ergaenzen-mutieren-mittels-abfrage-externer-daten-438456.html
Ausgedruckt am: 04.05.2025 um 00:05 Uhr
10 Kommentare
Neuester Kommentar

Wieso erst noch in der XML abändern, mach das doch gleich in den Objekten und gebe es dann als CSV aus
.
Eine Prüfung ob Prefix nicht vorhanden hast wirst du hoffentlich noch selbst mit einem if() hinbekommen
, das lass ich dir als Hausaufgabe.
$csvdb = Import-CSV 'D:\prefixdb.csv' -Delimiter ";"
$xml = [xml](gc 'D:\import.xml')
$items = @()
foreach($part in $xml.PRODUCTS.SPAREPARTS){
$prefix = $csvdb | ?{$_.HERSTELLERNAME -eq $part.'FATHER-HERST-NAME'} | select -Expand 'HERSTELLER-PREFIX'
$items += [pscustomobject]@{
'MY-FATHER-NR' = "$prefix-$($part.'FATHER-HERST-NR')"
'FATHER-LIEF-NR' = $part.'FATHER-LIEF-NR'
'FATHER-HERST-NR' = "$($part.'FATHER-HERST-NAME') $($part.'FATHER-HERST-NR')"
'FATHER-HERST-NAME' = $part.'FATHER-HERST-NAME'
'MY-PART-NR' = "$prefix-$($part.'PART-HERST-NR')"
'PART-LIEF-NR' = $part.'PART-LIEF-NR'
'PART-HERST-NR' = "$($part.'PART-HERST-NAME') $($part.'PART-HERST-NR')"
'PART-HERST-NAME' = $part.'PART-HERST-NAME'
}
}
$items | export-csv 'd:\export.csv' -Delimiter ";" -NoType -Encoding UTF8

'PRIN_ART_NO' = @{$true="$prefix-$($part.Code)";$false="$prefix-$($part.SupplierCode)"}[($part.SupplierCode -eq "")]
p.s. oben noch beschleunigt.

Wie verknüpfe ich mehrere Abfragen im IF?
Wie wär's zwischendurch mal mit Handbuch lesen?-and
-or
https://goo.gl/search/powershell+logical+operators

If () {
}elseif (){
}elseif (){
}else(){
}
Oder
Switch($var){
'bla' {}
'blub' {}
}
https://www.windowspro.de/script/if-else-switch-bedingte-anweisungen-pow ...
Oder eben wie ich dir oben schon gezeigt habe mit einer Hashtable mit mehreren Wertpaaren welche anhand des Ergebnisses in den eckigen Klammern ausgewählt wird.
}elseif (){
}elseif (){
}else(){
}
Oder
Switch($var){
'bla' {}
'blub' {}
}
https://www.windowspro.de/script/if-else-switch-bedingte-anweisungen-pow ...
Oder eben wie ich dir oben schon gezeigt habe mit einer Hashtable mit mehreren Wertpaaren welche anhand des Ergebnisses in den eckigen Klammern ausgewählt wird.
'PRIN_ART_NO' = @{'Ergebnis1'='Wert1';'Ergebnis2'='Wert2';'Ergebnis3'='Wert3'}[$part.WasauchimmerdieErgebnisseliefert]

Gut, diese Bedingung war mir ja nicht bekannt, das mit der Hashtable funktioniert hier dann nicht das geht nur um das Ergebnis einer Bedingung zu erhalten.
Für das was du da hast ist das If...Elseif..Else...Endif Konstrukt das Richtige, damit kannst du beliebig viele Elseif Zweige benutzen und einer Variablen den gewünschten Wert zuweisen. Das setzt du vor das CustomObjekt und deklarierst eine Variable in der du den gewünschten Inhalt ausgibst. Im CustomObjekt setzt du dann passend die gerade erzeugte Variable ein
Fertig.
Für das was du da hast ist das If...Elseif..Else...Endif Konstrukt das Richtige, damit kannst du beliebig viele Elseif Zweige benutzen und einer Variablen den gewünschten Wert zuweisen. Das setzt du vor das CustomObjekt und deklarierst eine Variable in der du den gewünschten Inhalt ausgibst. Im CustomObjekt setzt du dann passend die gerade erzeugte Variable ein
'PRIN_LIEFERSTATUS' = $variable