Hilfe bei XML bearbeiten mit PowerShell
Hallo zusammen,
ich komme bei meinen Problem einfach nicht mehr weiter.
Ich muss in einer XML Datei die 10-stellige Nummer aus der Zeile 20 auslesen und dann die Zeilen 20 bis 22 mit dem Inhalt aus Zeile 20 neu abspeichern
es handelt sich um die Zeilen:
dies müssten so aussehen:
Ich habe schon viele Möglichkeiten probiert, aber alles hat nichts gebracht.
Bin schon am verzweifeln, deshalb hätte ich auch schon ChatGPT gefragt, aber da kommt auch kein Ergebnis raus.
Bin um jede Hilfe dankbar
ich komme bei meinen Problem einfach nicht mehr weiter.
Ich muss in einer XML Datei die 10-stellige Nummer aus der Zeile 20 auslesen und dann die Zeilen 20 bis 22 mit dem Inhalt aus Zeile 20 neu abspeichern
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--created on 14.07.2023 12:26:47 SoftTracToAppl: 7.16.1 , ESStaBO: 3.0.3-->
<Batch ID="445462" Application="AZHSCAN@" Name="AZHscan_4_230714_700000_00484" xsi:noNamespaceSchemaLocation="file:c:\program files\SofttracToAppl\Batch.xsd" xmlns:tns="http://www.elsag-solutions.com/xmlDoc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Attributes>
<BatchName>AZHscan_4_230714_700000_00484</BatchName>
<OutPath>\\cpdivaimg01-8.intra.vsa.de\nprod_scanner\</OutPath>
<Date>2023-07-14</Date>
<Time>12:26:47</Time>
<Station>4</Station>
<User>TEST</User>
<UserBatchinput InputName="BOXNO">700000</UserBatchinput>
<IPath>/images/azh1_Prod/scan</IPath>
</Attributes>
<Documents>
<Document ID="0">
<Pages>
<Page ID="0">
<Front>
<Attributes>
<Barcode ID="5100" DataType="string">0139956605</Barcode>
<Barcode ID="5101" DataType="string">000001111118</Barcode>
<Paginator ID="9000">319540637936</Paginator>
</Attributes>
<Images>
<Image ID="0" Path="AZHscan_4_230714_700000_00484\00063793_0.jpg" Date="2023-07-14" Time="12:26:47" ImgType="3" DPI="200" Height="1662" Width="1181" Size="81557">
</Image>
<Image ID="1" Path="AZHscan_4_230714_700000_00484\00063793_1.tif" Date="2023-07-14" Time="12:26:47" ImgType="2" DPI="200" Height="1662" Width="1181" Size="8117">
</Image>
</Images>
</Front>
<Rear>
<Attributes>
<FormReco ID="57" FormType="FormBEB" Confidence="2.94">
</FormReco>
</Attributes>
<Images>
<Image ID="2" Path="AZHscan_4_230714_700000_00484\00063793_2.jpg" Date="2023-07-14" Time="12:26:47" ImgType="3" DPI="200" Height="1663" Width="1186" Size="46215">
</Image>
<Image ID="3" Path="AZHscan_4_230714_700000_00484\00063793_3.tif" Date="2023-07-14" Time="12:26:47" ImgType="2" DPI="200" Height="1663" Width="1186" Size="1688">
</Image>
</Images>
</Rear>
</Page>
<Page ID="1">
<Front>
<Attributes>
<Barcode ID="5100" DataType="string">0002222226</Barcode>
<Barcode ID="5101" DataType="string">319540637943</Barcode>
<Paginator ID="9000">319540637943</Paginator>
</Attributes>
<Images>
<Image ID="0" Path="AZHscan_4_230714_700000_00484\00063794_0.jpg" Date="2023-07-14" Time="12:26:47" ImgType="3" DPI="200" Height="828" Width="1147" Size="34992">
</Image>
<Image ID="1" Path="AZHscan_4_230714_700000_00484\00063794_1.tif" Date="2023-07-14" Time="12:26:47" ImgType="2" DPI="200" Height="828" Width="1147" Size="3351">
</Image>
</Images>
es handelt sich um die Zeilen:
<Barcode ID="5100" DataType="string">0139956605</Barcode>
<Barcode ID="5101" DataType="string">000001111118</Barcode>
<Paginator ID="9000">319540637936</Paginator>
dies müssten so aussehen:
<Barcode ID="5000" DataType="string">000001111118</Barcode>
<Barcode ID="5100" DataType="string">0139956605</Barcode>
<Barcode ID="5101" DataType="string">000001111118</Barcode>
Ich habe schon viele Möglichkeiten probiert, aber alles hat nichts gebracht.
Bin schon am verzweifeln, deshalb hätte ich auch schon ChatGPT gefragt, aber da kommt auch kein Ergebnis raus.
Bin um jede Hilfe dankbar
Please also mark the comments that contributed to the solution of the article
Content-ID: 7850120026
Url: https://administrator.de/contentid/7850120026
Printed on: October 9, 2024 at 22:10 o'clock
25 Comments
Latest comment
Ich muss in einer XML Datei die 10-stellige Nummer aus der Zeile 20 auslesen und dann die Zeilen 20 bis 22 mit dem Inhalt aus Zeile 20 neu abspeichern
Also nur die Nummer in den 3 Knoten gleich machen?? Dann:$xml = New-Object XML
$xml.Load("D:\source.xml")
$attributes = $xml.SelectSingleNode('/Batch/Documents/Document[@ID=0]/Pages/Page[@ID=0]/Front/Attributes')
$attributes.Barcode[1].innerText = $attributes.Barcode[0].innerText
$attributes.Paginator.innerText = $attributes.Barcode[0].innerText
$xml.Save("D:\neu.xml")
<Barcode ID="5100" DataType="string">0139956605</Barcode>
<Barcode ID="5101" DataType="string">000001111118</Barcode>
<Paginator ID="9000">319540637936</Paginator>
<Barcode ID="5100" DataType="string">0139956605</Barcode>
<Barcode ID="5101" DataType="string">0139956605</Barcode>
<Paginator ID="9000">0139956605</Paginator>
das "zu weit eingerückte" bitte nicht beachten, war ein Copy-Fehler
Dann korrigiere es doch bitte das man hier weiß was Sache sein soll. darfst du auch am Freitag ...Ein "Ist => Soll" sollte man doch hinbekommen !
Zeppel
Na dann
$xml = New-Object XML
$xml.Load("D:\source.xml")
$attributes = $xml.SelectSingleNode('/Batch/Documents/Document[@ID=0]/Pages/Page[@ID=0]/Front/Attributes')
$number = $attributes.Barcode[0].innerText
$attributes.Barcode[0].Id = "5000"
$attributes.Barcode[0].innerText = "000001111118"
$attributes.Barcode[1].Id = "5100"
$attributes.Barcode[1].innerText = $number
[void]$attributes.RemoveChild($attributes.Paginator)
$newNode = $attributes.Barcode[1].CloneNode($false)
$newNode.Id = "5101"
$newNode.innerText = "000001111118"
$attributes.AppendChild($newNode)
$xml.Save("D:\neu.xml")
$Source = 'C:\Temp\'
$files = Select-String -Pattern 'Beleg ausserhalb der Lieferung im Stapel null Beleg 0' -SimpleMatch -Path "$Source\*.error" -Exclude "*.xml.error" -List | select -Expand Path
Foreach ($File in $files){
$xml = New-Object XML
$xml.Load($File)
$attributes = $xml.SelectSingleNode('/Batch/Documents/Document[@ID=0]/Pages/Page[@ID=0]/Front/Attributes')
$number = $attributes.Barcode[0].innerText
$attributes.Barcode[0].Id = "5000"
$attributes.Barcode[1].Id = "5100"
$attributes.Barcode[1].innerText = $number
$attributes.Barcode[0].innerText = "000001111118"
$newNode = $attributes.Barcode[1].CloneNode($false)
$newNode.Id = "5101"
$newNode.innerText = "000001111118"
$attributes.AppendChild($newNode)
$attributes.RemoveChild($attributes.Paginator)
$xml.Save($file)
}
Bitte dann How can I mark a post as solved?
aber das passt leider nicht ganz.
Dann hast du es oben aber völlig falsch beschrieben"die 10-stellige Nummer aus der Zeile 20 auslesen und dann die Zeilen 20 bis 22 mit dem Inhalt aus Zeile 20 neu abspeichern."
Nicht nur Kollege @7426148943 sondern jeder normal Denkende interpretiert das so das alle Zeilen von 20 bis 22 den identischen Wert "0139956605" haben.
Fehlermeldung lesen hilft ...
Deine XML Dateien sind fehlerhaft
Deine XML Dateien sind fehlerhaft
Ungültige Daten auf Stammebene. Zeile 1, Position 1.";
Dann verstehst du vermutlich auch nicht was ich mit nicht korrekt meine.
Die Meldung kommt zu 99% dann, wenn das Encoding in der XML-Declaration nicht mit dem tatsächlichen Encoding der Datei übereinstimmt. Z.B. auch wenn die Datei ein BOM hat.
Wenn das der Fall ist wirst du wohl den Inhalt mit Get-Content einlesen und als XML umwandeln müssen.
Enconding bei Get-Content bei Bedarf anpassen.
Ohne die Files hier vorliegen zu haben natürlich ohne Gewähr... Glaskugel am Freitag eben.
Aber die XML sind nicht fehlerhaft, die kommen von einer Maschine und werden vom System wieder eingelesen und das ohne Probleme
Das die Maschine sie liest heißt nicht das sie auch korrekt ist, sie ignoriert wohl nur das Encoding.Die Meldung kommt zu 99% dann, wenn das Encoding in der XML-Declaration nicht mit dem tatsächlichen Encoding der Datei übereinstimmt. Z.B. auch wenn die Datei ein BOM hat.
Wenn das der Fall ist wirst du wohl den Inhalt mit Get-Content einlesen und als XML umwandeln müssen.
Enconding bei Get-Content bei Bedarf anpassen.
Ohne die Files hier vorliegen zu haben natürlich ohne Gewähr... Glaskugel am Freitag eben.
$Source = 'C:\Temp\'
$files = Select-String -Pattern 'Beleg ausserhalb der Lieferung im Stapel null Beleg 0' -SimpleMatch -Path "$Source\*.error" -Exclude "*.xml.error" -List | select -Expand Path
Foreach ($File in $files){
$xml = [xml](Get-Content $file -Encoding Default)
$attributes = $xml.SelectSingleNode('/Batch/Documents/Document[@ID=0]/Pages/Page[@ID=0]/Front/Attributes')
$number = $attributes.Barcode[0].innerText
$attributes.Barcode[0].Id = "5000"
$attributes.Barcode[1].Id = "5100"
$attributes.Barcode[1].innerText = $number
$attributes.Barcode[0].innerText = "000001111118"
$newNode = $attributes.Barcode[1].CloneNode($false)
$newNode.Id = "5101"
$newNode.innerText = "000001111118"
$attributes.AppendChild($newNode)
$attributes.RemoveChild($attributes.Paginator)
$xml.Save($file)
}
Wo liegt da der Fehler?
Schau dir meinen Code in Zeile 2 nochmal genau an dann siehst du warum, du expandiert die Property nicht. Du bekommst ja von Select-String ein Object mit mehreren Eigenschaften geliefert und der Pfad steht nur in der Property PathWie ihr seht, hat die Ursprungs-Datei eine zusätliche ".error"-Endung, dies müsste bei dem neuen Namen entfernt werden
Replace ist dein Freund# ....
$newpath = $file -replace '\.error$'
$xml.Save($newpath)
Nö, klappt hier im Test einwandfei ... Siehe mein Code.
Du kannst Zeile 3 auch so schreiben, kommt auf das gleiche drauf raus.
Du kannst Zeile 3 auch so schreiben, kommt auf das gleiche drauf raus.
$Result = Get-ChildItem "$Source\*" -File -Include *.error -Exclude *.xml.error | ?{(Get-Content $_.Fullname -Raw) -like '*Beleg ausserhalb der Lieferung im Stapel null Beleg*' | Select -ExpandProperty Fullname
mit diesem Code hat er die komplette Endung gelöscht.
Tja deswegen sollte seine Fragen besser schreiben du wolltest in deinem Satz nur die Endung entfernen nicht durch eine andere ersetzen 😀Ich bin jetzt raus, du hast jetzt das nötige Handwerkszeug und die anfängliche Frage des Threads und die anderen wurden hinreichend beantwortet.
So denn viel Spaß noch mit der PS.
Zeppel
Zitat von @Haberl92:
In meiner Frage habe ich gesagt, dass die Datei eine zusätzliche Endung hat (sieht man auch im Code)
Eben und warum sollte man da nochmal ".xml" anhängen wenn es doch schon vorhanden ist, entfernen reicht hier ja dann??In meiner Frage habe ich gesagt, dass die Datei eine zusätzliche Endung hat (sieht man auch im Code)
$xml.Load("C:\Temp\AZHscan_4_230714_700000_00484.xml.error"
"C:\Temp\AZHscan_4_230714_700000_00484.xml.error" -replace '\.error$'
C:\Temp\AZHscan_4_230714_700000_00484.xml
"C:\Temp\AZHscan_4_230714_700000_00484.xml.error" -replace '\.error$','.xml'
C:\Temp\AZHscan_4_230714_700000_00484.xml.xml
@7426148943
ich danke dir vielmals für deine Hilfe.
Bidde.ich danke dir vielmals für deine Hilfe.
Zitat von @Haberl92:
wie oben erwähnt nehme ich den Dateinamen aus einer gleichnamigen Datei, welche nur die "error"-Endung hat.
Wusste ich nicht dachte die XML ist die in der du den Inhalt findest, dann ist es klar, hier weiß ja niemand wie der Inhalt der Datei überhaupt aussieht in der die Dateinamen stehen ... Du siehst von Anfange gleich eindeutig beschreiben hat Vorteile .wie oben erwähnt nehme ich den Dateinamen aus einer gleichnamigen Datei, welche nur die "error"-Endung hat.