1

I'm trying to generate a batch file to rename all the .xml files based on specific attribute Niv=. However, I have not managed to make such a modification.

This the code that at the time supported me to generate works with noIdentificacion node, but I need to find Niv= in file of which contents is added below.

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
REM Change the current directory: your choice
pushd "C:\Users\Javier Preciado\Desktop\sistemas\"
REM Get a static list of `xml` files
for /f "delims=" %%Z in ('dir /b *.xml') do (
    REM clear a sentinel flag
    set "_Niv="
    REM Search for a particular text string in a file
    for /f "delims=" %%A in ( 'find /i "Niv=" ^< "%%Z"' ) do (
        REM The FOR command is mostly used to process a set of one or more files, 
        REM     but you can also process a set of one or more text strings: 
        for %%G in ( %%A ) do (
            REM debugging output
            echo debug %%G
            REM found the particular text string in the line?
            if /I "%%~G"=="Niv" (
                set "_Niv=Niv" REM set the sentinel flag
            ) else (
                if defined _noIdentificacion (
                    REM debugging output
                    echo found Niv in file "%%~Z": "%%~G"
                    REM check as to whether a file isn't renamed already 
                    if EXIST "%%~Z" if /I "%%~Z" NEQ "%%~G.xml" (
                        REM remove ECHO from next line no sooner than debugged
                        ren "%%~Z" "%%~G.xml"
                    )
                )
                REM clear the sentinel flag
                set "_Niv="
            )
        )
    )
)
REM Change directory back to the path/folder most recently stored by the PUSHD command.
popd

Contents of XML file:

<?xml version="1.0" encoding="UTF-8" ?><cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ventavehiculos="http://www.sat.gob.mx/ventavehiculos" xmlns:terceros="http://www.sat.gob.mx/terceros" xmlns:Toyota="http://www.pegasotecnologia.com/secfd/Schemas" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd http://www.sat.gob.mx/ventavehiculos http://www.sat.gob.mx/sitio_internet/cfd/ventavehiculos/ventavehiculos11.xsd http://www.sat.gob.mx/terceros http://www.sat.gob.mx/sitio_internet/cfd/terceros/terceros11.xsd http://www.pegasotecnologia.com/secfd/Schemas http://www.pegasotecnologia.com/secfd/Schemas/AddendaEmisorToyota.xsd" Version="3.3" Serie="A" Folio="000814547" Fecha="2017-12-01T15:27:55" Moneda="MXN" TipoCambio="1" SubTotal="292556.52" Total="338928.57" FormaPago="99" CondicionesDePago="Inmediato" TipoDeComprobante="I" MetodoPago="PPD" LugarExpedicion="45110" NoCertificado="00001000000402850319" Certificado="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" Sello="LV1beEcSeRBLjmIrZV6wwQ5TcYQkYeuekAKtAmgRsGD5EezvevH4gv3+93E8Wk9CxBJNVRYLHLlG3uxR7rXawpBTbgPJFCPSt3a0q+Rb3OnBdu8BAdu/lNi4lGojrgzcbthZnPD0u9WoJOiDFI4494wUDR4dF2WJr+8QYYxSfXtMQV065dOrDDtmfJektPIS0hq1JAkknHpThExjX8s0UuV2+MVTciu+DVXoa4G5wp0ldLCWLSzsR5iXulATCEgodrynw5/kvLKqZkI2GAy5oCO2GA0REHFosIlISuNBhD08fcEOwju+NVHKGdjXZ89YpkCXMVxhrL0CQVHZ1dxuNQ=="><cfdi:Emisor Rfc="TMS010508RX0" Nombre="TOYOTA MOTOR SALES DE MEXICO S DE RL DE CV" RegimenFiscal="601" /><cfdi:Receptor Rfc="OAU021125H84" Nombre="OZ AUTOMOTRIZ S DE RL DE CV" UsoCFDI="P01" /><cfdi:Conceptos><cfdi:Concepto ClaveProdServ="25101500" NoIdentificacion="56012018" Cantidad="1.00" ClaveUnidad="EA" Unidad="EA" Descripcion="Hiace Panel Van Super Long" ValorUnitario="283717.25" Importe="283717.25"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base="283717.25" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="45394.76" /></cfdi:Traslados></cfdi:Impuestos><cfdi:InformacionAduanera NumeroPedimento="17  51  3788  7004005" /><cfdi:ComplementoConcepto><ventavehiculos:VentaVehiculos version="1.1" ClaveVehicular="1520202" Niv="JTFPX22PXJ0080089"><ventavehiculos:InformacionAduanera numero="1701842" fecha="2017-11-28" aduana="Lazaro Cardenas" /></ventavehiculos:VentaVehiculos></cfdi:ComplementoConcepto></cfdi:Concepto><cfdi:Concepto ClaveProdServ="01010101" NoIdentificacion="560120181" Cantidad="1.00" ClaveUnidad="EA" Unidad="EA" Descripcion="Manejo, procesamiento y entreg" ValorUnitario="6108.07" Importe="6108.07"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base="6108.07" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="977.29" /></cfdi:Traslados></cfdi:Impuestos></cfdi:Concepto><cfdi:Concepto ClaveProdServ="01010101" NoIdentificacion="5601201823" Cantidad="1.00" ClaveUnidad="EA" Unidad="EA" Descripcion="Otros cargos DTM" ValorUnitario="2320.00" Importe="2320.00"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base="2320.00" Impuesto="002" TipoFactor="Exento" /></cfdi:Traslados></cfdi:Impuestos><cfdi:ComplementoConcepto><terceros:PorCuentadeTerceros version="1.1" rfc="DTM020315Q47" nombre="Distribuidores Toyota México, A.C."><terceros:Impuestos><terceros:Traslados><terceros:Traslado impuesto="IVA" tasa="0" importe="0.00" /></terceros:Traslados></terceros:Impuestos></terceros:PorCuentadeTerceros></cfdi:ComplementoConcepto></cfdi:Concepto><cfdi:Concepto ClaveProdServ="01010101" NoIdentificacion="5601201824" Cantidad="1.00" ClaveUnidad="EA" Unidad="EA" Descripcion="Otros cargos DTM" ValorUnitario="371.20" Importe="371.20"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base="371.20" Impuesto="002" TipoFactor="Exento" /></cfdi:Traslados></cfdi:Impuestos><cfdi:ComplementoConcepto><terceros:PorCuentadeTerceros version="1.1" rfc="DCO050303BG1" nombre="DTMAC Comercializadora, S.A. de C.V."><terceros:Impuestos><terceros:Traslados><terceros:Traslado impuesto="IVA" tasa="0" importe="0.00" /></terceros:Traslados></terceros:Impuestos></terceros:PorCuentadeTerceros></cfdi:ComplementoConcepto></cfdi:Concepto><cfdi:Concepto ClaveProdServ="01010101" NoIdentificacion="5601201825" Cantidad="1.00" ClaveUnidad="EA" Unidad="EA" Descripcion="Otros cargos DTM" ValorUnitario="40.00" Importe="40.00"><cfdi:Impuestos><cfdi:Traslados><cfdi:Traslado Base="40.00" Impuesto="002" TipoFactor="Exento" /></cfdi:Traslados></cfdi:Impuestos><cfdi:ComplementoConcepto><terceros:PorCuentadeTerceros version="1.1" rfc="FME930525J6A" nombre="Fundacion Merced, A.C."><terceros:Impuestos><terceros:Traslados><terceros:Traslado impuesto="IVA" tasa="0" importe="0.00" /></terceros:Traslados></terceros:Impuestos></terceros:PorCuentadeTerceros></cfdi:ComplementoConcepto></cfdi:Concepto></cfdi:Conceptos><cfdi:Impuestos TotalImpuestosTrasladados="46372.05"><cfdi:Traslados><cfdi:Traslado Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="46372.05" /></cfdi:Traslados></cfdi:Impuestos><cfdi:Complemento><tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/timbrefiscaldigital/TimbreFiscalDigitalv11.xsd" Version="1.1" UUID="E3A64D3C-1F89-4620-B005-A021B109FB23" FechaTimbrado="2017-12-01T15:27:55" RfcProvCertif="SST060807KU0" SelloCFD="LV1beEcSeRBLjmIrZV6wwQ5TcYQkYeuekAKtAmgRsGD5EezvevH4gv3+93E8Wk9CxBJNVRYLHLlG3uxR7rXawpBTbgPJFCPSt3a0q+Rb3OnBdu8BAdu/lNi4lGojrgzcbthZnPD0u9WoJOiDFI4494wUDR4dF2WJr+8QYYxSfXtMQV065dOrDDtmfJektPIS0hq1JAkknHpThExjX8s0UuV2+MVTciu+DVXoa4G5wp0ldLCWLSzsR5iXulATCEgodrynw5/kvLKqZkI2GAy5oCO2GA0REHFosIlISuNBhD08fcEOwju+NVHKGdjXZ89YpkCXMVxhrL0CQVHZ1dxuNQ==" NoCertificadoSAT="00001000000405179095" SelloSAT="DsTXSzE+CTI+c6cobTFhLee2nsQVC+l0Fnjy2+5OTGTUpTWUj7FjpSw/tgHsiSNijTVKuiGuQFanSj2AmZImM6PXaPe06cEpt11PQ6ABOzR2PZpJ0Eanf3/YwpOu4/fyH3euZS/dtLIfZpFOrwAZlhJ7zQCLS7cv2q5dnLRRz9o1PD0yTv/7ECm3mPE30eWXKjsmg46HckzY+mxDWFWmpmhfQGR/PhimThQBq03+WO78ycresk67q5jM1rvmGzNPnh9UIKAEAH4NSsdrCt0jgkff2vOeYCVmsuhBf/y4L9FXid/vAdGS7xMgaBMEP9e1AnEBW1IppbUCaKMZe2jX4g==" /></cfdi:Complemento><cfdi:Addenda><Toyota:AddendaEmisor><Toyota:Toyota><Toyota:Datos email="facturacionelectronica@toyotagdl.com.mx" distFd="57011" fechaEmbarque="2017-11-28" facturaTms="1701842" claveVehicular="1520202" color="058 ICEBERG / FR13 FR13" usado="usado" numMotor="2TR -9145818" otrosCargos="6108.07" netoPagar="338928.57" /></Toyota:Toyota></Toyota:AddendaEmisor></cfdi:Addenda></cfdi:Comprobante>
Mofi
  • 46,139
  • 17
  • 80
  • 143
PAPI PAPI
  • 25
  • 4
  • What does rename using node position mean? Is the XML content always just a single line? What efforts have you made towards achieving your goal yourself? What is the reasoning behind choosing a scripting solution which does not have native XML abilities? – Compo Dec 29 '17 at 20:45

1 Answers1

0

It is a very bad idea to process XML files with Windows command interpreter which is designed for just executing commands and applications. cmd.exe has no XML parsing capabilities or at least enhanced string handling functions.

XML files contain lots of < and > and = and " which have all a special meaning for Windows command interpreter which makes processing lines from XML files very difficult in a batch file.

XML files are often Unicode encoded using UTF-8 which is a character encoding not used by default by Windows command interpreter which uses a single byte per character encoding with an OEM code page depending on region and language setting of used user account. This could be problematic if the value to process contains a non ASCII character. It looks like in this case the value of attribute Niv contains always only ASCII characters.

And on XML files without newline characters the file size being in this case the length of the single line is another problem for processing such XML files with Windows command interpreter because the length of a command line and the maximum length of an environment variable are limited to just a few KiB as it can be read for example at

  1. Environment Variables (Microsoft documentation page)
  2. Command prompt (Cmd.exe) command-line string limitation (Microsoft troubleshooting page)
  3. What is the maximum length of an environment variable? (developer blog article by Raymond Chen)
  4. What is the command line length limit? (developer blog article by Raymond Chen)

Those limitations are problematic for doing this file renaming task based on value of attribute Niv. The batch file below works around the command line length limitation by using the batch file JREPL.BAT written by Dave Benham. This batch file must be extracted from the ZIP file into the directory of the batch file (or any other directory on modifying line 10 of the batch file as described above). It is of course also possible to use any other solution listed on How can you find and replace text in a file using the Windows command-line environment? to insert CR+LF after each > in temporary copy of an XML file with no newline characters.

Here is the commented batch file for this file renaming task which should have been better done with other scripting languages.

@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\sistemas"

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 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 Niv 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 Niv everything from begin of
rem the line to Niv and including Niv itself is removed from the line.
rem So the remaining XML line starts with an equal sign and the value
rem of attribute Niv 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 Niv
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 " Niv=\"..*\"" %1 >nul 2>&1
if errorlevel 1 goto :EOF
set "XmlFile=%~1"

:GetXmlLine
for /F "delims=" %%J in ('%SystemRoot%\System32\findstr.exe /R " Niv=\"..*\"" "%XmlFile%"') do (
    set "XmlLine=%%J"
    goto GetNivValue
)

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

:GetNivValue
if "%XmlFile:~-3%" == "tmp" del "%XmlFile%"
setlocal EnableDelayedExpansion
set "XmlLine=!XmlLine:* Niv=!"
for /F "delims=>    = " %%J in ("!XmlLine!") do endlocal & set "NivValue=%%~J"

if /I "%NivValue%.xml" == "%~nx1" goto :EOF

if not exist "%NivValue%.xml" ren "%~1" "%NivValue%.xml" & goto :EOF
echo Error: File "%NivValue%.xml" exists already.
echo        File %1 cannot be renamed for that reason.
set "MessageOutput=1"
goto :EOF

Note: In line 87 below label :GetNivValue with the FOR command line there must be a horizontal tab character between > and = after delims= and not four spaces as displayed by the browser. If all your XML files never contain a tab character instead of a space character, the tab character displayed as 4 spaces can be also removed completely from this line.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • popd /?
  • pushd /?
  • rem /?
  • ren /?
  • set /?
  • setlocal /?

Read also the Microsoft article about Using command redirection operators for an explanation of
>nul, 2>nul and 2>&1. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded
dir command line with using a separate command process started in background.

And read Single line with multiple commands using Windows batch file explaining operator & used on some command lines in provided batch file code.

Mofi
  • 46,139
  • 17
  • 80
  • 143