Batch para renombrar múltiples archivos xml en base a 2 etiquetas dentro del mismo
Estoy intentado modificar un batch para que me renombre múltiples archivos xml de acuerdo a 2 etiquetas que existen dentro del mismo (Serie y Folio) la idea es que cada archivo se renombre uniendo el valor de ambas etiquetas ejemplo si el archivo original se llama FACTURAXML201901.XML y las etiquetas de Serie y Folio contienen los siguientes valores Serie= "B" y Folio="000525747"el archivo debería renombrarse a B000525747.XML y así sucesivamente por cada archivo que se encuentre en la misma carpeta.
El código que tengo ya hace el trabajo pero solo con un valor de etiqueta y no he podido ajustarlo para que pueda unir los valores de las 2 etiquetas y renombrar cada archivo.
Utilizo 2 .bat para poder renombrar los archivos
Código del primer archivo Timex_Partes.bat que a su vez manda llamar al segundo JREPL.bat
Los archivos están en la siguiente ruta.
https://drive.google.com/drive/folders/1EFAG0W0nmLc6Ffsr5q2xKOqEoEj7eBPK?usp=sharing
1 Respuesta
Le he echado un vistazo a los archivos del enlace. El Jrepl.bat me ha parecido muy, muy interesante y pienso estudiarlo a fondo pero por lo que he visto no interviene concretamente en el renombrado (aunque se haga referencia a él en el otro bat, supongo que para otras cosas). He retocado el Timex_Partes.bat para que haga lo que pretendes. Así es como me ha quedado:
::*****RENOMBRA ARCHIVOS... ::*************************************** @echo off setlocal EnableExtensions DisableDelayedExpansion set "MessageOutput=" rem Define name of replace tool jrepl.bat with full path. It is expected by rem the code below that this batch file is stored in same directory as the rem batch file. It is of course also possible to have this tool stored in rem a different directory in which case %~dp0 must be replaced by path of rem this directory. set "ReplaceTool=%~dp0jrepl.bat" rem Change the current directory to the directory specified below. pushd "%USERPROFILE%\Desktop\timex2019_Partes\" rem Get and process a static list of XML files. for /F "delims=" %%I in ('dir *.xml /A-D /B 2^>nul') do call :ProcessXmlFile "%%I" rem JREPL.BAT v7.9 leaves behind JREPL\XBYTES.HEX in folder for temporary files. rd /Q /S "%TEMP%\JREPL" 2>nul rem Restore initial current directory. popd rem Pause script execution if an error message was output because a file rem could not be renamed because of an already existing file with same name. if defined MessageOutput echo/ & pause rem Restore initial environment which means also discarding all environment rem variables defined in this batch file and restore the initial values of rem all other environment variables. endlocal rem Exit processing of this batch file. goto :EOF rem Subroutine ProcessXmlFile reads first line containing case-sensitive rem attribute Folio with a value having at least one character in double rem quotes. Nothing is done if the XML file of which name is passed as rem first argument to the subroutine does not contain such an attribute. rem Both commands of the FOR loop are not executed if the line output by rem FINDSTR is too long for being assigned to environment variable XmlLine. rem In this case it can be expected that the XML file to process contains rem no newline characters. For that reason a copy of the not pretty formatted rem XML file is made with JREPL batch file with file extension TMP instead of rem XML with inserting after every right angle bracket the Windows text file rem line ending characters carriage return (\r) and line-feed (\n). Then the rem temporary file is searched by FINDSTR returning now hopefully a much rem shorter line which can be processed by the Windows command interpreter. rem The temporary file is deleted finally in any case. rem From the XML line containing attribute Folio everything from begin of rem the line to Folio and including Folio itself is removed from the line. rem So the remaining XML line starts with an equal sign and the value rem of attribute Folio enclosed in double quotes. Needed is only the rem attribute value inside the double quotes. rem After having the attribute value it is first checked if the file rem has already the right file name in which case the subroutine can rem be exited immediately and processing continues in main FOR loop. rem Next is checked if no *.xml file with this value as file name exists rem already in current directory. The current XML file is renamed to Folio rem attribute value if this precondition is true. Otherwise an information rem is output and later batch file execution is halted so that the user rem can read this message after finishing processing of all XML files. :ProcessXmlFile echo %1 %SystemRoot%\System32\findstr.exe /R " Folio=\"..*\"" %1 >nul 2>&1 if errorlevel 1 goto :EOF set "XmlFile=%~1" :GetXmlLine for /F "delims=" %%J in ('%SystemRoot%\System32\findstr.exe /R " Folio=\"..*\"" "%XmlFile%"') do ( set "XmlLine=%%J" goto GetFolioValue ) if "%XmlFile:~-3%" == "tmp" del "%XmlFile%" & goto :EOF call "%ReplaceTool%" ">" ">\r\n" /XSEQ /F "%XmlFile%" /O "%TEMP%\%~n1.tmp" set "XmlFile=%TEMP%\%~n1.tmp" goto GetXmlLine :GetFolioValue if "%XmlFile:~-3%" == "tmp" del "%XmlFile%" setlocal EnableDelayedExpansion set "XmlLine=!XmlLine:* Folio=!" for /F "delims=> = " %%J in ("!XmlLine!") do endlocal & set "FolioValue=%%~J" rem identificacion de la serie si existe for /F "delims=" %%J in ('%SystemRoot%\System32\findstr.exe /R " Serie=\"..*\"" "%XmlFile%"') do ( set "XmlLine=%%J" goto GetSerieValue ) :GetSerieValue if "%XmlFile:~-3%" == "tmp" del "%XmlFile%" setlocal EnableDelayedExpansion set "XmlLine=!XmlLine:* Serie=!" for /F "delims=> = " %%J in ("!XmlLine!") do endlocal & set "SerieValue=%%~J" if /I "%SerieValue%%FolioValue%.xml" == "%~nx1" goto :EOF if not exist "%SerieValue%%FolioValue%.xml" ren "%~1" "%SerieValue%%FolioValue%.xml" & goto :EOF echo Error: File "%SerieValue%%FolioValue%.xml" exists already. echo File %1 cannot be renamed for that reason. set "MessageOutput=1" goto :EOF
Como algunas veces el editor de la página hace cosas raras quiero dejar claro cuales son los cambios realizados. Están en las líneas finales del archivo, a partir de la línea que dice "rem identificacion de la serie si existe" y básicamente introducen un tratamiento para la "Serie" similar al que ya figura para el "Folio". Funciona para el caso que aparece en el enlace (archivo FACTURAXML201901.xml), pero no me extrañaría que haya otros aspectos con los que pueda interferir de modo que no cantaremos "victoria" de momento.
Pruébalo y ya me dirás.
Estimado la modificación que has echo ha quedado funcionando al 100% te agradezco de sobremanera el apoyo brindado ya que en otras ocasiones me has echado la mano.
Recibe un cordial saludo.
Y de nuevo muchísimas gracias.
Buena tarde estimado disculpa la molestia fíjate que me he tomado con un archivo el cual necesito guardarlo en base a 3 equetas sin embargo llevo varios días intentando adaptar el archivo que me hiciste favor de adecuar pero no he podido, si tienes oportunidad le puedes echar un vistazo para ver que me esta faltando.
link de archivos
https://drive.google.com/drive/folders/1bLMqNGZZ-on4gpyuO83NZKi4PLpWnCq5?usp=sharing
Si aplicas tu bat (Times_Partes_3etiquetas) al xml de la primera prueba (FACTURAXML201901.xml) funciona correctamente. En cambio no ocurre lo mismo con el prueba3.xml. Voy a intentar averiguar la razón, pero ahora no tengo tiempo.
No hay problema estimado cualquier apoyo es bienvenido y gracias por responder. Voy a investigar yo también, pero creo que el tema va relacionado a que etiqueta "remision" se repite varias veces y no se si eso sea el motivo por el cual no lo puede tomar el proceso.
Pero de nuevo muchas gracias por el apoyo, saludos.
Hice una prueba buscando solo 1 etiqueta la de remisión y utilizando solo esa si funciona, no se porque no quiere funcionar combinando otras.
Me da la impresión de que el problema puede estar relacionado con la longitud de línea de los archivos XML utilizados. Las instrucciones de los BAT pueden tener problemas para manejar líneas de más de 4096 caracteres. He comprobado que si aplicas el Timex_Partes.bat corregido por mí (fecha 13 de junio, solo dos etiquetas) al prueba3.xml, no lo trata bien.
Por fin he podido dedicarle un tiempo a este asunto. He editado el prueba3.xml insertando "cambios de línea Windows/MSDOS" (es decir, la combinación CRLF, de carriage return + line feed, también conocida como return o intro) siempre que una línea superaba los 4096 caracteres, pero eligiendo el final de tag/etiqueta más cercano a ese límite, para distorsionar lo mínimo posible el archivo XML, sin hacer ningún otro cambio en el texto del archivo, y de esa manera funciona correctamente. Por tanto considero que esto confirma mi impresión de que era la longitud de línea de ese archivo la que causaba el problema. Por si quieres probarlo te he dejado en
https://drive.google.com/open?id=19EY_hs3QTaL5TMyAaWUjzARyy9Wl6W-z
Esa variante del prueba3.xml con el nombre de prueba3v.xml.
Si fuera normal que los archivos XML que tienes que tratar tengan líneas de más de 4096 caracteres creo que habría que olvidarse de la shell MSDOS/CMD para pasar a utilizar la PowerShell de Windows, mucho más potente y moderna pero que solo conozco un poco. Te recuerdo que para los comandos de MSDOS/CMD que tratan líneas (como el FOR) la línea termina cuando encuentra el fin de línea (CRLF). Si se alcanzan los 4096 caracteres sin haber detectado un fin de línea no se "carga" la línea.
¡Gracias! Por la información estimado, me ha servido de mucho para comprender la forma en que se procesan los archivos. Y ahora me queda claro habrá que meterse al tema de powershell.
De nuevo gracias por tu tiempo.
Saludos.
Había algo que no me acababa de cuadrar en mi explicación, y es el hecho de que el archivo del primer caso (FACTURAXML201901.xml) está formado por una sola línea de 6145 caracteres, lo que impediría que el FOR la tratara bien si solo admitiera líneas de menos de 4096. Como sabía que en otras ocasiones había tropezado con problemas de este tipo repasé mis actuaciones en la página y en Como usar el comando Diskpart encontré que el que tiene esa limitación es el comando TYPE (que a veces se usa dentro de un FOR). De modo que decidí explorar las limitaciones del FOR (porque tenía claro que en nuestro caso eran las limitaciones del FOR las que estaban involucradas) y me he encontrado con que el FOR no admite líneas de más de 8181 caracteres (un número sorprendente porque esperaba encontrarme 8192 que es el doble de 4096, pero eso es lo que me ha salido). Eso explica que el FACTURAXML201901.xml no dé problemas. Bueno, con esto doy por cerrado este asunto. Y, efectivamente, parece que tendrás que plantearte trabajar con PowerShell.
- Compartir respuesta