pat.bat
Goto Top

PowerShell - XML bestimmte Node auslesen und Inhalt ersetzen

Hallo zusammen,

ich versuche gerade eine generierte xml Datei per Powershell abzuändern, bzw ein bestimmtes Node muss geändert werden, danach soll die XML wieder abgespeichert werden. Ich habe mir dazu schon einige Anleitungen auf Google angeschaut, aber ich komme nicht zum Erfolg.

Dazu erstmal ein Ausschnitt aus der XML:

<?xml version="1.0" encoding="utf-8"?>  
<Document xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 pain.001.001.03.xsd" xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>DTA-Bank.Zahllauf</MsgId>
<CreDtTm>2019-08-01T17:03:01</CreDtTm>
<NbOfTxs>71</NbOfTxs>
<CtrlSum>7055.60</CtrlSum>
<InitgPty>
<Nm>Landkreis Musterhausen</Nm>
</InitgPty>
</GrpHdr>
<PmtInf>
<PmtInfId>123400000002095</PmtInfId>
<PmtMtd>TRF</PmtMtd>
<NbOfTxs>71</NbOfTxs>
<CtrlSum>7055.60</CtrlSum>
<PmtTpInf>
<SvcLvl>
<cd>SEPA</cd>
</SvcLvl>
</PmtTpInf>
<ReqdExctnDt>2019-08-02</ReqdExctnDt>
<Dbtr>
<Nm>Landkreis Musterhausen</Nm>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>DEXXXXXXXXXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>NOLADE21LWL</BIC>
</FinInstnId>
...
...

Dabei geht es mir nur um diese Node: <ReqdExctnDt>2019-08-02</ReqdExctnDt>
Dieses soll immer in + 1 Tag abgeändert werden.

Mein derzeitiger Versuch sieht so aus:

Push-Location $(Split-Path $Script:MyInvocation.MyCommand.Path) # Skriptpfad bestimmen

$xml = [xml](Get-Content .\SEPA-CCT.xml)

# Für jedes Element in der XML Datei unter 'ReqdExctnDt' durchlaufen              
foreach ($element in (Select-Xml -Xml $xml -XPath '//ReqdExctnDt'))              
{            
    
    if ($element.Node.InnerText -like "2019-08-02")              
        {            
          
            $element.Node.InnerText  = "2019-08-03"                     
        }            

    # Speichern der XML Datei am ursprünglichen Ort            
    $xml.Save(".\SEPA-CCT.xml")  
}

Pop-Location

Ich bin mir dabei ehrlich gesagt nicht sicher ob ich das mit dem XPath richtig angehe. Laut Anleitungen sieht das aber so aus wie es sein sollte. Außer ich habe was falsch verstanden.
Er scheint wohl das Element nicht zu finden. Ich habe es auch schon mit dem kompletten Nodepfad versucht aber auch kein Erfolg.

Kann mir bitte jemand sagen, wo genau der Fehler liegt? Vll liegt es auch an der Struktur der xml, das es nicht ganz so einfach ist :S

Vielen Dank im Voraus.

Content-Key: 480860

Url: https://administrator.de/contentid/480860

Printed on: April 18, 2024 at 12:04 o'clock

Member: erikro
erikro Aug 02, 2019 at 08:04:29 (UTC)
Goto Top
Moin,

mach mal ein $ vor die Klammer:

foreach ($element in $(Select-Xml -Xml $xml -XPath '//ReqdExctnDt'))  

oder etwas übersichtlicher imho:

$elements = Select-Xml -Xml $xml -XPath '//ReqdExctnDt'  
foreach ($element in $elements)

hth

Erik
Mitglied: 140447
140447 Aug 02, 2019 updated at 08:28:32 (UTC)
Goto Top
Du hast den xmlns-Namespace des Root-Elements bei deiner XPath Query nicht beachtet, deswegen ist der Select immer leer face-wink.
So klappt der Select, Bsp :
https://tio.run/##nVA9a8MwFNz9K4QoZJIlO0sqbMdDuqWlNEugdBDyayywJdd6rg2lv9 ...

mach mal ein $ vor die Klammer:
Das ist nicht nötig, normale Klammern reichen hier völlig aus. Das Dollarzeichen brauchst du nur wenn das Konstrukt innerhalb von einem String zur Anwendung kommt.
Member: emeriks
emeriks Aug 02, 2019 at 08:30:30 (UTC)
Goto Top
Zitat von @erikro:
mach mal ein $ vor die Klammer:
Warum? Muss man nicht.
Member: Pat.bat
Pat.bat Aug 02, 2019 at 08:56:41 (UTC)
Goto Top
@140447 Der Select funktioniet jetzt einwandfrei. Nur will er es noch nicht speichern, es kommt aber auch kein Fehler. hab ich da was übersehen oder was könnte der Grund sein, warum die $xml.Save Anweisung nicht funktioniert?

Der Wert der Node.InnerText wurde vorher korrekt geändert, aber das Dokument wird nicht abgespeichert.
Mitglied: 140447
Solution 140447 Aug 02, 2019 updated at 09:15:11 (UTC)
Goto Top
Ist doch klar, du machst die Änderungen nur an einem Select auf ein virtuell existentes Objekt und nicht am Objekt $xml selbst , deswegen ändert sich auch nüscht😁. Am einfachst du lässt select-xml weg und nutzt die Methode .SelectSingleNode des $xml Objects. Aber nicht den Namespace vergessen ;)

$file = 'D:\Ordner\SEPA-CCT.xml'  
$xml = [xml](gc $file)
[System.Xml.XmlNamespaceManager]$ns = new-Object System.Xml.XmlNamespaceManager $xml.NameTable
$ns.AddNamespace("ns",$xml.DocumentElement.NamespaceURI)  
$xml.SelectSingleNode("//ns:ReqdExctnDt",$ns) | %{  
    $_.'#text' = (get-date $_.'#text').AddDays(1).toString("yyyy-MM-dd")  
}
$xml.Save($file)
Mitglied: 140447
140447 Aug 02, 2019 updated at 10:12:52 (UTC)
Goto Top
Wenn's das dann war bitte noch den Haken dran.
Member: Pat.bat
Pat.bat Aug 02, 2019 at 11:00:35 (UTC)
Goto Top
@140447 Was hat es mit dem '#text' auf sich oder ist das nur ein Platzhalter?

Vielen Dank schonmal für die Hilfe.
Mitglied: 140447
140447 Aug 02, 2019 updated at 11:06:51 (UTC)
Goto Top
Zitat von @Pat.bat:

@140447 Was hat es mit dem '#text' auf sich oder ist das nur ein Platzhalter?
Nein kein Platzhalter, das ist die Property des Nodes welche den eigentlichen String des Elements enthält.
Lass dir einfach mal $_ in der Konsole ausgeben dann siehst du es das es eine Eigenschaft des zurückgegebenen Objects ist. Denn der Textinhalt ist in XML ebenfalls ein Node (Text-Node).