XML Datei auslesen und schreiben mit Powershell
Hallo zusammen,
ich muss mehrere XML Dateien bearbeiten . Normalerweise benutze ich, um einzelne Elemente in Dateien zu ändern und auszulesen, die cmd.exe. Bei Text Dateien funktioniert das auch immer sehr gut. Nun kommt es aber beim Zerlegen von XML Dateien immer wieder zu Problemen wie Sonderzeichen oder das Limit von Token. Deshalb möchte ich das zum Anlass nehmen, um mich in die Powershell einzuarbeiten. Leider habe ich da keine Erfahrung und hoffe, dass ich hier etwas Hilfe bekomme.
Die XML Dateien sehen etwa so aus.
Innerhalb einer solchen Struktur benötige ich nur eine Zeile (<part part_one=“Wert). Hier benötige ich den Wert von „part_two“ und „part_sixty-five“ diese beiden Werte sollen durch einen Punkt getrennt, nach „part_two“ geschrieben werden und der Rest soll so erhalten bleiben. Bei der cmd.exe hätte ich zeilenweise die Datei ausgelesen, mit IF Else auf die Zeile gewartet, diese dann zerlegt und wieder zusammengesetzt. Nun die Frage, wie setze ich das aber nun mit der Powershell um? Die beiden benötigten Werte habe ich mir wie folgt mal „zusammengeschustert“.
Leider weiß ich nun nicht weiter bzw. ob das so überhaupt der richtige Ansatz ist?!?
Die Werte stehen vor P_ARTICLE_MANUFACTURER="xxx" und P_ARTICLE_PARTNR="xxx"
Vielen Dank
ich muss mehrere XML Dateien bearbeiten . Normalerweise benutze ich, um einzelne Elemente in Dateien zu ändern und auszulesen, die cmd.exe. Bei Text Dateien funktioniert das auch immer sehr gut. Nun kommt es aber beim Zerlegen von XML Dateien immer wieder zu Problemen wie Sonderzeichen oder das Limit von Token. Deshalb möchte ich das zum Anlass nehmen, um mich in die Powershell einzuarbeiten. Leider habe ich da keine Erfahrung und hoffe, dass ich hier etwas Hilfe bekomme.
Die XML Dateien sehen etwa so aus.
<?xml version="1.0" encoding="utf-8" ?>
<partsmanagemement count=“1“ ….>
<part part_one=“Wert“ part_two=”Wert” usw…2000.Zeichen.>
<…>
<…>
</part>
</partmanagement>
<partsmanagemement count=“1“ ….>
…
Innerhalb einer solchen Struktur benötige ich nur eine Zeile (<part part_one=“Wert). Hier benötige ich den Wert von „part_two“ und „part_sixty-five“ diese beiden Werte sollen durch einen Punkt getrennt, nach „part_two“ geschrieben werden und der Rest soll so erhalten bleiben. Bei der cmd.exe hätte ich zeilenweise die Datei ausgelesen, mit IF Else auf die Zeile gewartet, diese dann zerlegt und wieder zusammengesetzt. Nun die Frage, wie setze ich das aber nun mit der Powershell um? Die beiden benötigten Werte habe ich mir wie folgt mal „zusammengeschustert“.
$meinstring = Select-String -Path .\datei.xml -Pattern P_ARTICLE_PARTNR
$teil1 = "$meinstring".Split('"') ; $teil1[5]
$teil2 = "$meinstring".Split('"') ; $teil2[65]
Die Werte stehen vor P_ARTICLE_MANUFACTURER="xxx" und P_ARTICLE_PARTNR="xxx"
Vielen Dank
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 623872
Url: https://administrator.de/contentid/623872
Ausgedruckt am: 24.11.2024 um 18:11 Uhr
4 Kommentare
Neuester Kommentar
Kein Thema ... aber lass den "Shiet" mit dem Split Powerhell kann XML nativ parsen, in Objekte zerlegen und mittels XPath passende Knoten selektieren!
btw. dein hier gepostetes XML ist übrigens nicht valide, es hat mehrere Root(DocumentElement)-Knoten und das kann eine XML nicht, eine XML kann nur ein einziges "DocumentElement" besitzen! Außerdem hat deine XML diverse Rechtschreibfehler sogar in den Knoten die du selektieren willst, deswegen muss ich hier den tatsächlichen Namen mal wieder raten.
Deswegen gehe ich einfach mal von folgender XML-Datei aus (die ist wenigstens valide )
Falls es dich interessiert wie man mittels XPath bestimmte Knoten selektiert die den gewünschten Kriterien entsprechen (so wie es die Funktion "SelectNodes" hier tut) dann beliest du dich hier
https://www.w3schools.com/xml/xpath_syntax.asp
Im Beispiel Xpath werden nur die "part" Elemente selektiert die auch deine beiden genannten Attribute besitzen
Nur diese werden geändert und am Ende die XML wieder gespeichert.
ACHTUNG HINWEIS!: Anpassungen könnten nötig werden wenn du uns hier Teile mit XML "Namespaces" in deiner XML verschwiegen hast.
Gruß P.
$file = 'D:\Datei.xml'
$xml = [xml](gc $file)
$xml.SelectNodes("//partsmanagement/part[@part_two and @part_sixty-five]") | %{
$_.part_two = "$($_.part_two).$($_.'part_sixty-five')"
}
$xml.Save($file)
btw. dein hier gepostetes XML ist übrigens nicht valide, es hat mehrere Root(DocumentElement)-Knoten und das kann eine XML nicht, eine XML kann nur ein einziges "DocumentElement" besitzen! Außerdem hat deine XML diverse Rechtschreibfehler sogar in den Knoten die du selektieren willst, deswegen muss ich hier den tatsächlichen Namen mal wieder raten.
Deswegen gehe ich einfach mal von folgender XML-Datei aus (die ist wenigstens valide )
<?xml version="1.0" encoding="utf-8"?>
<root>
<partsmanagement count="1">
<part part_one="Wert" part_two="Hallo" part_sixty-five="Test">
<whatever />
<whatever />
</part>
<part part_one="Wert" part_sixty="Test">
<whatever />
<whatever />
</part>
</partsmanagement>
</root>
Falls es dich interessiert wie man mittels XPath bestimmte Knoten selektiert die den gewünschten Kriterien entsprechen (so wie es die Funktion "SelectNodes" hier tut) dann beliest du dich hier
https://www.w3schools.com/xml/xpath_syntax.asp
Im Beispiel Xpath werden nur die "part" Elemente selektiert die auch deine beiden genannten Attribute besitzen
//partsmanagement/part[@part_two and @part_sixty-five]
Nur diese werden geändert und am Ende die XML wieder gespeichert.
ACHTUNG HINWEIS!: Anpassungen könnten nötig werden wenn du uns hier Teile mit XML "Namespaces" in deiner XML verschwiegen hast.
Gruß P.
Kannst es ja einfach mal selbst probieren und folgenden invaliden Code mit zwei DocumentElements ausführen:
Bringt dir folgende Error-Message
Wenn das wirklich so wäre könntest du aber meinen obigen Code überhaupt erst gar nicht laufen lassen weil sich der Parser vorher schon beschweren würde. Denke das war nur ein Copy n Paste Fehler von deiner Seite.
Na denn.
Gruß P.
[xml]@'
<?xml version="1.0" encoding="utf-8"?>
<root>
</root>
<root>
</root>
'@
Bringt dir folgende Error-Message
annot convert value "<?xml version="1.0" encoding="utf-8"?>
<root>
</root>
<root>
</root>" to type "System.Xml.XmlDocument". Error: "Das Dokument verfügt bereits über einen 'DocumentElement'-Knoten."
At line:1 char:1
+ [xml]@'
+ ~~~~~~~
+ CategoryInfo : InvalidArgument: (:) , RuntimeException
+ FullyQualifiedErrorId : InvalidCastToXmlDocument
Wenn das wirklich so wäre könntest du aber meinen obigen Code überhaupt erst gar nicht laufen lassen weil sich der Parser vorher schon beschweren würde. Denke das war nur ein Copy n Paste Fehler von deiner Seite.
Na denn.
Gruß P.