robdox
Goto Top

XML Tag auslesen und in Dateinamen anreichern

Hallo,

ich möchte ein XML Tag einer XML Datei auslesen lassen (LIFNR) die Werte innerhalb des Tags sollen dann an den Dateinamen angefügt werden: LIFNR_Dateiname.xml

Ich hab ein Skript gestern geschrieben, welches soweit funktionierte. Der Hintergrund ist alle XML Dateien welche sich im Order XY befinden, sollen umbenannt werden. Im heutigen Test funktioniert nur noch die 1. Datei, dann werden Fehlermeldungen zurückgeliefert, dass der Dateiname nicht mehr gefunden wird. Da ich kein Profi in Batchprogrammierung bin, bräuchte ich hier Hilfe. Evtl auch gern einen anderen Denkanstoß.


Mein Code der Datei:

:: Bereich / Variablen lokal setzen
@echo off & setlocal 
set "Ordner=C:\Test"  

:: Ordner nach XML Datein durchsuchen
 pushd "%Ordner%"  
  for /f "delims=" %%i in ('dir /b/a-d *.xml') do call :ProcessFile "%%i"  
 popd
 
goto :eof

:: XML Dateien, wenn gefunden, abändern
:ProcessFile

set "Titel="  

:: Suche nach XML-Tag LIFNR (Kreditorennummer)
for /f "delims=" %%b in ('dir /b/a-d *.xml') do set "file=%%b"  
   for /f "delims=" %%a in ('powershell -Executionpolicy ByPass -command "([xml](gc '%Ordner%\%file%')).SelectSingleNode('//LIFNR').innerText"') do set "titel=%%a"  
     set "NameNeu=%file%"  
	 :: Wenn Titel gefüllt, benenne Dateinamen mit Kreditorennummer um
     if defined Titel set "NameNeu=%titel%_%NameNeu%"  
      ren %file% "%NameNeu%"  
 popd
 
goto :eof

Vielen Dank vorab, für jede Hilfe!

Content-ID: 445944

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

Ausgedruckt am: 22.11.2024 um 12:11 Uhr

Kraemer
Lösung Kraemer 30.04.2019 um 09:09:17 Uhr
Goto Top
Moin,

warum kapselst du Powershell in eine Batch anstatt das Ganze gleich direkt in Powershell umzusetzen?


Gruß
erikro
Lösung erikro 30.04.2019 um 09:22:22 Uhr
Goto Top
Moin,

ein ungetesteter Powershell-Einzeiler:

get-childitem *.xml | foreach-object { rename-item -newname "$([xml]$(get-content $_.fullname).SelectSingleNode('//LIFNR').innerText).xml" }  

Ich hoffe das funktioniert so. Wenn nicht, dann melde Dich mit den Fehlermeldungen. face-wink Ist der Wert nicht vorhanden, gibt es hässliche Fehlermeldungen. Außerdem sollte man noch abfangen, ob die Datei schon exisitiert.

hth

Erik
robdox
robdox 30.04.2019 um 09:34:19 Uhr
Goto Top
Vielen Dank schonmal für die Hilfe!

Ich kapsel es, weil ich mit PS nicht so firm bin, bzw mich gerade an beidem versuche (ich bin aber gern offen für eine bessere Lösung, das Ganze soll am ende als Aufgabenplan aller 5 Minuten durchlaufen für Ordner XY und die Dateien abändern (welche täglich neu importiert werden von einem anderen System)

Ich habe das PS Skript ausgeführt:

Cmdlet Rename-Item an der Befehlspipelineposition 1
Geben Sie Werte für die folgenden Parameter an:
Path: C:\KREDITOR_20190415-092422-328.xml
Fehler beim Aufrufen der Methode, da [System.String] keine Methode mit dem Namen "SelectSingleNode" enthält.  
In C:\Rename.ps1:2 Zeichen:42
+ ...        rename-item -newname "$([xml]$(get-content $_.fullname).Select ...  
+                                           ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) , RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

Wie implementiere ich nun im Powershell, dass alle Dateien aus einem Ordner Xy ausgelesen und umbenannt werden?
Kraemer
Lösung Kraemer 30.04.2019 um 09:51:48 Uhr
Goto Top
auf die Schnelle ungetestet

$Path="C:\temp"  
$ChildPath="*.xml"  

$Files=Join-Path -Path $Path -ChildPath $ChildPath -Resolve

foreach ($File in $Files){
    $LIFNR=([xml](gc $File)).SelectSingleNode('//LIFNR').innerText  
    Rename-Item -Path $File -NewName "$LIFNR_$File"  
}
robdox
robdox 30.04.2019 um 10:00:45 Uhr
Goto Top
vielen Dank! Soweit für mich einleuchtend - jedoch werden keine Dateien umbenannt. Muss hier noch mit -Executionpolicy gearbeitet werden?
erikro
Lösung erikro 30.04.2019 um 10:52:00 Uhr
Goto Top
Moin,

wie gesagt, ist das ungetestet. face-wink Lass mal das .fullname hinter $_ weg.

hth

Erik
robdox
robdox 30.04.2019 um 11:55:44 Uhr
Goto Top
Alles gut. Habe getestet, leider bekomme ich keine Änderung hin. Es kommt kein Fehler mehr, aber auch keine Ausführung des Ganzen.

Ist das so "kompliziert" oder stell ich mich hier an....

Danke vorab!
erikro
Lösung erikro 30.04.2019 um 12:15:58 Uhr
Goto Top
Zeig mal ein XML als Beispiel. Bitte das ganze. Die Daten kannst Du ja gerne anonymisieren.
robdox
robdox 30.04.2019 um 12:22:12 Uhr
Goto Top
Hier eine BSP-Datei, wird von SAP erzeugt und abgerufen für internes System.

<?xml version="1.0" encoding="ISO-8859-1"?>  
<CREMAS06>
<IDOC BEGIN="1">  
<EDI_DC40 SEGMENT="1">  
<TABNAM>EDI_DC40</TABNAM>
<MANDT>100</MANDT>
<DOCNUM>0000000009335468</DOCNUM>
<DOCREL>740</DOCREL>
<STATUS>30</STATUS>
<DIRECT>1</DIRECT>
<OUTMOD>2</OUTMOD>
<IDOCTYP>CREMAS06</IDOCTYP>
<MESTYP>CREMAS</MESTYP>
<SNDPOR>SAPEP1</SNDPOR>
<SNDPRT>LS</SNDPRT>
<SNDPRN>EP1CLNT100</SNDPRN>
<RCVPOR>PP1</RCVPOR>
<RCVPRT>LS</RCVPRT>
<RCVPRN>LOGSYSM3</RCVPRN>
<CREDAT>20190423</CREDAT>
<CRETIM>125429</CRETIM>
<SERIAL>20190423125340</SERIAL>
</EDI_DC40>
<E1LFA1M SEGMENT="1">  
<MSGFN>018</MSGFN>
<LIFNR>0000293209</LIFNR>
<BBBNR>0000000</BBBNR>
<BBSNR>00000</BBSNR>
<BUBKZ>0</BUBKZ>
<ERDAT>20160511</ERDAT>
<ERNAM>STEITZK</ERNAM>
<KTOKK>0005</KTOKK>
<LAND1>PL</LAND1>
<NAME1>xxx</NAME1>
<NAME2>xxx</NAME2>
<ORT01>xxx</ORT01>
<PSTLZ>78-640</PSTLZ>
<SORTL>SENAT</SORTL>
<SPRAS>D</SPRAS>
<STRAS>xxx</STRAS>
<TELF1>xxxx</TELF1>
<STCEG>xxx</STCEG>
<ADRNR>xxx</ADRNR>
<MCOD1>xxx</MCOD1>
<MCOD2>xxx</MCOD2>
<MCOD3>TUCZNO</MCOD3>
<GBDAT>00000000</GBDAT>
<REVDB>00000000</REVDB>
<WERKR>X</WERKR>
<DUEFL>X</DUEFL>
<TAXBS>0</TAXBS>
<STAGING_TIME> 0</STAGING_TIME>
<E1LFA1A SEGMENT="1">  
<QSSYSDAT>00000000</QSSYSDAT>
<RGDATE>00000000</RGDATE>
<RIC>00000000000</RIC>
<RNEDATE>00000000</RNEDATE>
<LEGALNAT>0000</LEGALNAT>
</E1LFA1A>
<E1LFB1M SEGMENT="1">  
<MSGFN>004</MSGFN>
<LIFNR>0000293209</LIFNR>
<BUKRS>5000</BUKRS>
<ERDAT>20181219</ERDAT>
<ERNAM>xxx</ERNAM>
<ZUAWA>055</ZUAWA>
<AKONT>0000441000</AKONT>
<ZWELS>ILS</ZWELS>
<ZTERM>I000</ZTERM>
<BUSAB>AP</BUSAB>
<ZINDT>00000000</ZINDT>
<ZINRT>00</ZINRT>
<DATLZ>00000000</DATLZ>
<WEBTR>0</WEBTR>
<KULTG> 0</KULTG>
<REPRF>X</REPRF>
<QSZDT>00000000</QSZDT>
<INTAD>xxx</INTAD>
<CERDT>00000000</CERDT>
<PERNR>00000000</PERNR>
<SMTP_ADDR>xxx</SMTP_ADDR>
</E1LFB1M>
<E1LFBKM SEGMENT="1">  
<MSGFN>018</MSGFN>
<LIFNR>0000293209</LIFNR>
<BANKS>xxx</BANKS>
<BANKL>xxx</BANKL>
<BANKN>xxx</BANKN>
<BKONT>xxx</BKONT>
<BANKA>xxx</BANKA>
<SWIFT>xxx</SWIFT>
<BNKLZ>xxx</BNKLZ>
<IBAN_BANKS>xxx</IBAN_BANKS>
<IBAN_BANKL>xxx</IBAN_BANKL>
<IBAN>xxx</IBAN>
</E1LFBKM>
</E1LFA1M>
</IDOC>
</CREMAS06>
Kraemer
Lösung Kraemer 30.04.2019 um 12:49:07 Uhr
Goto Top
und DEINEN Code bitte auch
erikro
Lösung erikro 30.04.2019 um 13:06:30 Uhr
Goto Top
Danke. Jetzt hatte ich was zum Testen. face-wink Mein Fehler. Man darf das .xml nicht direkt dranhängen, da das sonst als eine Objekteigentschaft interpretiert wird. So geht's (getestet):


get-childitem *.xml | foreach-object { rename-item $_ -newname ($([xml]$(get-content $_)).SelectSingleNode('//LIFNR').innerText +".xml") }  
139374
Lösung 139374 30.04.2019 aktualisiert um 13:26:54 Uhr
Goto Top
Zitat von @erikro:

Danke. Jetzt hatte ich was zum Testen. face-wink Mein Fehler. Man darf das .xml nicht direkt dranhängen, da das sonst als eine Objekteigentschaft interpretiert wird. So geht's (getestet):


get-childitem *.xml | foreach-object { rename-item $_ -newname ($([xml]$(get-content $_)).SelectSingleNode('//LIFNR').innerText +".xml") }  

So geht's (getestet):
Funktioniert aber nur solange es den Knoten auch tatsächlich in der XML-Datei gibt, und der Ursprungsname der Datei hängt auch nicht dran :-P

$ordner = 'D:\Daten'  
gci $ordner -Filter *.xml -File  | %{
    $node = ([xml]$(gc $_.Fullname)).SelectSingleNode('//LIFNR')  
    if ($node){
        $newname = "$($node.innerText)_$($_.Basename).xml"  
        if (!(Test-Path "$ordner\$newname")){  
            rename-item $_.Fullname -newname $newname -force -verbose
        }else{
            write-host "Datei mit dem Namen '$newname' gibt es schon!" -F Yellow  
        }
    }
}
erikro
Lösung erikro 30.04.2019 um 15:37:17 Uhr
Goto Top
Zitat von @139374:
Funktioniert aber nur solange es den Knoten auch tatsächlich in der XML-Datei gibt,

Fehlerbehandlung ist was für Feiglinge. face-wink

und der Ursprungsname der Datei hängt auch nicht dran :-P

Mist, habe ich die Aufgabe wieder nicht richtig gelesen. face-wink
139374
Lösung 139374 30.04.2019 aktualisiert um 18:46:31 Uhr
Goto Top
Zitat von @erikro:
Fehlerbehandlung ist was für Feiglinge. face-wink
sudo rm -rf /
robdox
robdox 02.05.2019 um 11:08:36 Uhr
Goto Top
Danke an alle ! Funktioniert wunderbar !