Powershell Skript: XML-Dateien durchsuchen und vergleichen
Hallo Miteinander,
ich bin noch Anfänger was das Schreiben von Skripten für die Windows Powershell angeht, ich würde gerne mein Problem bzw. was ich vorhabe kurz erläutern.
Ich habe einen Ordner "Eingabe" in dem sich mehrere .xml Dateien mit folgender Struktur befinden
Ich möchte nun die Nummer im Feld "customers_article_number" vorgeben und es soll dann alle XML-Dateien durchsuchen und vergleichen und mir die entsprechenden Felder
Ich hoffe, dass das möglich ist, ich würde die Ausgangsnummer in "customers_article_number" von Hand in die Datei eintragen, oder gibt es eine nette Möglichkeit?
Das habe ich schon, aber ich weiß nicht, ob das richtig ist oder ob das der falsche Ansatz ist, so wie ich das verstehe, da würde er ja nur die 3 Felder nehmen, oder?
Vielen Dank
ich bin noch Anfänger was das Schreiben von Skripten für die Windows Powershell angeht, ich würde gerne mein Problem bzw. was ich vorhabe kurz erläutern.
Ich habe einen Ordner "Eingabe" in dem sich mehrere .xml Dateien mit folgender Struktur befinden
<line_items>
<line_item>
<line_item_number>1</line_item_number>
<customers_article_number>7321351321445330</customers_article_number>
<quantity_ordered>0</quantity_ordered>
<quantity_unit_ordered>PCE</quantity_unit_ordered>
<quantity_last_delivered>500</quantity_last_delivered>
<quantity_unit_last_delivered>PCE</quantity_unit_last_delivered>
<quantity_receipts_cumulated>131040</quantity_receipts_cumulated>
<quantity_unit_receipts_cumulated>PCE</quantity_unit_receipts_cumulated>
<quantity_receipts_cumulated_date_start>2000-01-01</quantity_receipts_cumulated_date_start>
<item_description>XXXXX</item_description>
<delivery_date_type>F</delivery_date_type>
<delivery_date>2025-02-24</delivery_date>
<schedule_state>1</schedule_state>
<frequency>2</frequency>
<place_of_discharge>WE</place_of_discharge>
Ich möchte nun die Nummer im Feld "customers_article_number" vorgeben und es soll dann alle XML-Dateien durchsuchen und vergleichen und mir die entsprechenden Felder
quantity_receipts_cumulated
und quantity_last_delivered
ausgeben.Ich hoffe, dass das möglich ist, ich würde die Ausgangsnummer in "customers_article_number" von Hand in die Datei eintragen, oder gibt es eine nette Möglichkeit?
Das habe ich schon, aber ich weiß nicht, ob das richtig ist oder ob das der falsche Ansatz ist, so wie ich das verstehe, da würde er ja nur die 3 Felder nehmen, oder?
$files = Get-ChildItem -Path c:\test_robin\eingabe\ -Filter *.xml
$files | Foreach-Object {
$doc = [XML] (Get-Content -Path $_.FullName)
$lPos = $doc.selectNodes("//customers_article_number")
$2Pos = $doc.selectNodes("//quantity_receipts_cumulated")
$lPos | select quantity_last_delivered
$2Pos | select quantity_receipts_cumulated
}
Vielen Dank
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 669960
Url: https://administrator.de/contentid/669960
Ausgedruckt am: 04.12.2024 um 19:12 Uhr
14 Kommentare
Neuester Kommentar
Ich habe ChatGPT befragt, der Code sieht erstmal pausibel aus.
Deine XML scheint allerdings nicht vollständig zu sein, es fehlen Closings z.B. für line_item.
Wenn deine XML weitere Verschachtelungen hat, wir der nachfolgende Code vermutlich nicht auf Anhieb funktionieren.
KI generierter Code, leicht angepasst durch mich:
Deine XML scheint allerdings nicht vollständig zu sein, es fehlen Closings z.B. für line_item.
Wenn deine XML weitere Verschachtelungen hat, wir der nachfolgende Code vermutlich nicht auf Anhieb funktionieren.
KI generierter Code, leicht angepasst durch mich:
Quelle: ChatGPT KI
# Definiere die Artikelnummer, nach der gesucht werden soll
# Artikelnummer, die gesucht werden soll
$targetArticleNumber = Read-Host "Bitte die Artikelnummer eingeben (customers_article_number)"
# Pfad zum Ordner mit den XML-Dateien
$inputFolder = "C:\Pfad\zu\eingabe"
# Alle XML-Dateien im Ordner einlesen
$xmlFiles = Get-ChildItem -Path $inputFolder -Filter *.xml
# Ergebnisspeicher initialisieren
$results = @()
foreach ($file in $xmlFiles) {
# XML-Datei laden
try {
$xml = [xml](Get-Content -Path $file.FullName)
} catch {
Write-Warning "Konnte Datei $($file.FullName) nicht einlesen."
continue
}
# Durchsuche <line_item> Elemente
foreach ($item in $xml.line_items.line_item) {
if ($item.customers_article_number -eq $targetArticleNumber) {
# Felder extrahieren
$result = [PSCustomObject]@{
FileName = $file.Name
CustomersArticleNumber = $item.customers_article_number
QuantityReceiptsCumulated = $item.quantity_receipts_cumulated
QuantityLastDelivered = $item.quantity_last_delivered
}
$results += $result
}
}
}
# Ergebnisse ausgeben
if ($results.Count -gt 0) {
Write-Host "Gefundene Einträge:" -ForegroundColor Green
$results | Format-Table -AutoSize
} else {
Write-Host "Keine passenden Einträge gefunden." -ForegroundColor Yellow
}
# Optional: Ergebnisse in eine CSV-Datei exportieren
$results | Export-Csv -Path "$inputFolder\Ergebnisse.csv" -NoTypeInformation -Encoding UTF8
$customers_article_number = Read-Host "Nummer eingeben"
$folder = "D:\Ordner"
foreach($file in Get-Childitem -LiteralPath $folder -File -Filter *.xml | ?{Select-XML -Path $_.Fullname -XPath "//customers_article_number[.='$customers_article_number']"}){
$xml = New-Object XML
$xml.Load($file.Fullname)
$xml.SelectNodes("//line_item[customers_article_number = '$customers_article_number']") | select @{n='Path';e={$file.Fullname}},quantity_last_delivered,quantity_receipts_cumulated
}
Oder noch schlanker
Beide Codes erfolgreich mit Beispieldateien getestet. Ne KI braucht es für sowas simples nicht.
$customers_article_number = Read-Host "Nummer eingeben"
$folder = "D:\Daten"
Select-XML -Path "$folder\*.xml" -XPath "//line_item[customers_article_number='$customers_article_number']" | select Path,@{n='quantity_last_delivered';e={$_.node.quantity_last_delivered}},@{n='quantity_receipts_cumulated';e={$_.node.quantity_receipts_cumulated}}
Beide Codes erfolgreich mit Beispieldateien getestet. Ne KI braucht es für sowas simples nicht.
Zitat von @pimp1310:
ahh ich muss leider nochmal korrigieren, es gibt den block "<line_items><line_item>" und das Feld "customers_article_number" mehrmals und auch diese nummer kann in einem xml Dokument mehrfach vorkommen.
ahh ich muss leider nochmal korrigieren, es gibt den block "<line_items><line_item>" und das Feld "customers_article_number" mehrmals und auch diese nummer kann in einem xml Dokument mehrfach vorkommen.
Berücksichtigen beide meiner Codes bereits.
deine Codes liefern mir leider kein Ergebnis.
Da passiert einfach nix.
Wenn deine XML-Dateien Namespaces verwenden musst du uns das auch sagen die muss man nämlich zwingend mit angeben wenn man XPath benutz, klappt hier nämlich einwandfrei!!Da passiert einfach nix.
Deswegen braucht man bei sowas am besten immer die ganze Datei von beginn an mit allen verwendeten Namespaces!
hatte deinen Code angepasst nach meinem verständnis das er mir anzeigen soll wenn keine ergebnisse und das er es mir exportiert
Ist falsch angepasst.Wenn mit Export dann so
$customers_article_number = Read-Host "Nummer eingeben"
$folder = "D:\Daten"
$export = "D:\results.csv"
$results = Select-XML -Path "$folder\*.xml" -XPath "//line_item[customers_article_number='$customers_article_number']" | select Path,@{n='quantity_last_delivered';e={$_.node.quantity_last_delivered}},@{n='quantity_receipts_cumulated';e={$_.node.quantity_receipts_cumulated}}
if ($results){
$results | export-csv -Path $export -Delimiter ";" -NoType -Encoding UTF8
write-host "Einträge gefunden und exportiert ..."
}else{
write-warning "Nichts gefunden"
}
Habe ich oben geschrieben. Eine XML Datei von Anfang an inklusive Namespace Statements.
Alles klar, wie vermutet ein Namespace im Einsatz, hiermit klappt es dann :
Bitte die Pfade anpassen und den Namespace http://www.XXX.de/UNIDOC im Skript deanonymisieren wenn du es bei dir verwenden willst
Bitte die Pfade anpassen und den Namespace http://www.XXX.de/UNIDOC im Skript deanonymisieren wenn du es bei dir verwenden willst
$customers_article_number = Read-Host "Nummer eingeben"
$folder = "D:\Daten"
$export = "D:\results.csv"
$results = Select-XML -Path "$folder\*.xml" -XPath "//ns:line_item[ns:customers_article_number='$customers_article_number']" -Namespace @{ns="http://www.XXX.de/UNIDOC"} | select Path,@{n='quantity_last_delivered';e={$_.node.quantity_last_delivered}},@{n='quantity_receipts_cumulated';e={$_.node.quantity_receipts_cumulated}}
if ($results){
write-host "Einträge gefunden und exportiert:"
$results | format-table -AutoSize
$results | export-csv -Path $export -Delimiter ";" -NoType -Encoding UTF8 -Force
}else{
write-warning "Nichts mit der Nummer '$customers_article_number' gefunden!"
}