@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set freePort=
set newPort=
REM Checking the default value in XML file located at the path
FOR /F tokens^=4^ delims^=^" %%A in (
'type %~dp0\wlp\usr\servers\defaultServer\server.xml ^| find "httpEndpoint host="'
) do (
echo: Default Port in XML = %%A
set /a startPort=%%A
)
echo myCurrent port %startPort%
:SEARCHPORT
netstat -o -n -a | find "LISTENING" | find ":%startPort% " > NUL
if "%ERRORLEVEL%" equ "0" (
echo "port unavailable %startPort%"
REM Here I want to ask user to enter a port number rather than hard-coded value ???
set /a startPort=9080
echo myNew port %startPort%
GOTO :SEARCHPORT
) ELSE (
echo "port available %startPort%"
set freePort=%startPort%
GOTO :FOUNDPORT
)
:FOUNDPORT
echo free %freePort%
REM here I want to change the value of the httpPort in XML and save the xml file, and then launch the default browser with https:\\localhost:<freePort>MyApp ???
)
@pause
server.xml内容为:
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>webProfile-7.0</feature>
<!-- <feature>localConnector-1.0</feature> -->
</featureManager>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint host="27" httpPort="5357" httpsPort="9443" id="defaultHttpEndpoint"/>
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<applicationMonitor updateTrigger="mbean"/>
答案 0 :(得分:2)
使用Windows命令解释程序处理XML文件非常糟糕。 cmd.exe
用于执行命令和应用程序,而不是用于解析XML文件和修改它们。使用C,C ++或C#编写可执行文件来完成此任务肯定要好得多,而不是使用批处理文件。
但是,这是一个注释批处理文件,用于将属性httpPort
的当前端口号替换为分配给XML文件NewPort
中必须存储的环境变量server.xml
的新端口号与批处理文件位于同一目录中。请阅读评论,因为此代码仍有一些限制,例如属性httpsPort
的数字必须与httpPort
的数量不同,否则会同时替换两个数字。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem First check if the file to modify exists in directory of batch file.
set "XmlFile=%~dp0server.xml"
if not exist "%XmlFile%" goto EndBatch
rem Define some environment variables which are needed later.
set "NewPort=47680"
set "LineNumber="
set "LineCount=0"
set "TmpFile=%TEMP%\%~n0.tmp"
rem Search for the line containing attribute httpPort and get its
rem line number and the line itself loaded into environment variables.
for /F "tokens=1* delims=:" %%I in ('%SystemRoot%\System32\findstr.exe /L /N /C:httpPort= "%XmlFile%" 2^>nul') do (
set "LineNumber=%%I"
set "PortLine=%%J"
)
rem If no line with attribute httpPort found, exit this batch file.
if not defined LineNumber goto EndBatch
rem Determine current number of attribute httpPort independent on where
rem this attribute is specified in the XML line and replace this number
rem in the line with the new port number as defined before.
rem It is required for this type of number replace that the other port
rem number for httpsPort is not the same number as current number for
rem httpPort as in this case both numbers would be replaced by the new
rem number. The attribute name and the equal sign cannot be included in
rem the string substitution as used here.
setlocal EnableDelayedExpansion
set "PortNumber=!PortLine:*httpPort=!"
for /F %%I in ("!PortNumber:~1!") do set "PortNumber=%%~I"
set "PortLine=!PortLine:"%PortNumber%"="%NewPort%"!"
endlocal & set "PortLine=%PortLine%"
rem Make sure the temporary file used next does not already exist.
del "%TmpFile%" 2>nul
rem Copy all lines from XML file to a temporary file including empty
rem lines with the exception of the line containing attribute httpPort
rem which is copied to temporary file with the modified port number.
for /F "tokens=1* delims=:" %%I in ('%SystemRoot%\System32\findstr.exe /R /N "^" "%XmlFile%" 2^>nul') do (
set "XmlLine=%%J"
set /A LineCount+=1
setlocal EnableDelayedExpansion
if not !LineCount! == %LineNumber% (
echo/!XmlLine!>>"%TmpFile%"
) else (
echo/!PortLine!>>"%TmpFile%"
)
endlocal
)
rem Overwrite original file with temporary file automatically deleted on success.
move /Y "%TmpFile%" "%XmlFile%" >nul
:EndBatch
endlocal
更好的方法是使用 Dave Benham 编写的JREPL.bat,这是一个批处理文件/ JScript混合,用于使用正则表达式替换XML文件中的值。
@echo off
if not exist "%~dp0server.xml" goto :EOF
set "NewPort=47681"
call "%~dp0jrepl.bat" "(httpPort=[\x22']?)\d*([\x22']?)" "$1%NewPort%$2" /I /F "%~dp0server.xml" /O -
通过使用jrepl.bat
,属性httpPort
的当前值是什么并不重要,它甚至可以是空字符串。这里使用的不区分大小写的正则表达式替换甚至可以处理属性httpPort
,其值包含在单引号而不是双引号中,或者根本不用引号括起来,尽管这对XML文件无效。
\x22
是"
的十六进制表示法,用于避免Windows命令解释器出现问题,因为搜索参数字符串本身用双引号括起来。