Regex 根据匹配的文本/参数修改XML中的重复单词/文本?
我有一个XML文件,包含以下内容:Regex 根据匹配的文本/参数修改XML中的重复单词/文本?,regex,xml,batch-file,cmd,Regex,Xml,Batch File,Cmd,我有一个XML文件,包含以下内容: <SubtitleTracks> <SubtitleTrack> <IsNotifying>true</IsNotifying> <Burned>false</Burned> <Default>false</Default> <Forced>false</Forced>
<SubtitleTracks>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>1</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>2</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
</SubtitleTracks>
真的
假的
假的
假的
0
1.
英语[美国之音]
英格
VobSub
0
VobSub
真的
假的
假的
假的
0
2.
英语[美国之音]
英格
VobSub
0
VobSub
部分可以在整个文件中重复多次
然而,结构总是完全相同的。本节中唯一的变化是:
<SourceId>0</SourceId>
<TrackNumber>1</TrackNumber>
0
1.
那么下一个问题是:
<SourceId>0</SourceId>
<TrackNumber>2</TrackNumber>
0
2.
等等
现在,false
总是这样
我想做的是仅当SourceId为0且TrackNumber为1时,才将false
更改为true
任何人都可以帮助将这些需求转换成批处理文件吗
编辑:我想我几乎已经得到了这个,但是它被什么东西噎住了,因为我一直得到的结果是false
@ECHO OFF
SETLOCAL
SET "sourcedir=C:\Test"
SET "destdir=C:\Test"
SET "filename1=%sourcedir%\TestOutput.txt"
SET "outfile=%destdir%\TestOutputFixed.txt"
SET "hotsection="
CALL :clear$
(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
rem if line contains `<SubtitleTrack>` we've entered hot section
ECHO "%%a"|FIND "<SubtitleTrack>">NUL
IF NOT ERRORLEVEL 1 SET "hotsection=y"
SET "saved="
IF DEFINED hotsection (
FOR /L %%r IN (100,1,999) DO IF NOT DEFINED saved IF NOT DEFINED $%%r SET "$%%r=%%a"&SET "saved=Y"
rem if line contains `</SubtitleTrack>` or `</SubtitleTracks>` then end-of-hotsection
SET "endhot="
SET "endtrack="
FOR /f "tokens=1delims= " %%w IN ("%%a") DO FOR %%x IN ("</SubtitleTrack>") DO IF "%%w"==%%x SET "endhot=Y"&IF
"</SubtitleTracks>"==%%x SET "endtrack=Y"
IF DEFINED endhot (
rem end-of-hotsection
rem check whether we have SourceID 0 and TrackNumber 1
SET "id0="&SET "track1="
FOR /f "tokens=1,*delims== " %%r IN ('SET $') DO (
IF "%%s"==""<SourceId>0" SET "id0=Y"
IF "%%s"==""<TrackNumber>1" SET "track1=Y"
)
rem found end-of-hotsection. now regurgitate saved lines and set `default` appropriately
FOR /f "tokens=2delims==" %%r IN ('SET $') DO (
echo "%%r"|FINDSTR /r /c:" *\<Default>" >NUL
IF ERRORLEVEL 1 (ECHO %%r) ELSE (
FOR /f "tokens=1delims=:" %%s IN ("%%r") DO (
IF defined track1 (IF DEFINED id0 (ECHO %%s true,) ELSE (ECHO %%s false,)) ELSE (ECHO %%s false,)
)
)
CALL :clear$
IF DEFINED endtrack SET "hotsection="
)
)
) ELSE (ECHO %%a)
)
)>"%outfile%"
GOTO :EOF
:clear$
:: remove variables starting $
FOR /F "delims==" %%z In ('set $ 2^>Nul') DO SET "%%z="
GOTO :EOF
@ECHO关闭
SETLOCAL
设置“sourcedir=C:\Test”
设置“destdir=C:\Test”
设置“filename1=%sourcedir%\TestOutput.txt”
设置“outfile=%destdir%\TestOutputFixed.txt”
设置“热节=”
呼叫:清除$
(
对于/f“usebackqdelims=“%%a IN”(“%filename1%”)DO(
rem如果行包含“`我们已进入热段”
回显“%%a”|查找“>NUL
如果不是错误级别1,则设置“hotsection=y”
设置“已保存=”
如果定义了热节(
对于(100,1999)中的/L%%r,如果未定义,则不保存如果未定义$%%r设置“$%%r=%%a”并设置“已保存=Y”
rem如果行包含``或``则为热节的结尾
设置“endhot=”
设置“endtrack=”
对于/f“tokens=1delims=“%%w IN(“%a”)DO FOR%%x IN(“”)DO IF“%%w”==%%x SET“endhot=Y”&IF
“”=%%x设置“结束轨迹=Y”
如果定义为endhot(
热段末端
rem检查是否有SourceID 0和TrackNumber 1
设置“id0=”&SET“track1=”
对于/f“tokens=1,*delims==”%%r IN('SET$')DO(
如果“%%s”==“0”设置为“id0=Y”
如果“%%s”==“1”设置“track1=Y”
)
rem找到了热段的结尾。现在,将保存的行反刍一遍,并适当地设置“default”
对于/f“tokens=2delims=”%%r IN('SET$')DO(
回显“%%r”| FINDSTR/r/c:*\”>NUL
如果错误级别1(回显%%r)为其他(
对于/f“tokens=1delims=:”%%s IN(“%%r”)DO(
如果定义了track1(如果定义了id0(ECHO%%s true,)否则(ECHO%%s false,)否则(ECHO%%s false,)
)
)
呼叫:清除$
如果定义了尾迹集“hotsection=”
)
)
)其他(回声%%a)
)
)>“%outfile%”
后藤:EOF
:清除$
::删除开始时的变量$
对于/F“delims=”%%z In('set$2^>Nul')DO set“%%z=”
后藤:EOF
输入XML文件:
$ cat subtitletracks.xml
<SubtitleTracks>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>1</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>2</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
</SubtitleTracks>
$ cat subtitletransform.xslt
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<!-- copy all nodes and attributes -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- when find a default node for which the SourceId = 0 and trackNumber = 1 -->
<xsl:template match="//SubtitleTrack/Default[../SourceTrack/SourceId = '0' and ../SourceTrack/TrackNumber = '1']">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<!-- assign value to true -->
<xsl:value-of select="'true'"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
$ xsltproc subtitletransform.xslt subtitletracks.xml
<?xml version="1.0"?>
<SubtitleTracks>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>true</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>1</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>2</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
</SubtitleTracks>
$cat subtitracks.xml
真的
假的
假的
假的
0
1.
英语[美国之音]
英格
VobSub
0
VobSub
真的
假的
假的
假的
0
2.
英语[美国之音]
英格
VobSub
0
VobSub
转换表:
$ cat subtitletracks.xml
<SubtitleTracks>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>1</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>2</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
</SubtitleTracks>
$ cat subtitletransform.xslt
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<!-- copy all nodes and attributes -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- when find a default node for which the SourceId = 0 and trackNumber = 1 -->
<xsl:template match="//SubtitleTrack/Default[../SourceTrack/SourceId = '0' and ../SourceTrack/TrackNumber = '1']">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<!-- assign value to true -->
<xsl:value-of select="'true'"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
$ xsltproc subtitletransform.xslt subtitletracks.xml
<?xml version="1.0"?>
<SubtitleTracks>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>true</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>1</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>2</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
</SubtitleTracks>
$cat subtitletransform.xslt
输出:
$ cat subtitletracks.xml
<SubtitleTracks>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>1</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>2</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
</SubtitleTracks>
$ cat subtitletransform.xslt
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<!-- copy all nodes and attributes -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- when find a default node for which the SourceId = 0 and trackNumber = 1 -->
<xsl:template match="//SubtitleTrack/Default[../SourceTrack/SourceId = '0' and ../SourceTrack/TrackNumber = '1']">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<!-- assign value to true -->
<xsl:value-of select="'true'"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
$ xsltproc subtitletransform.xslt subtitletracks.xml
<?xml version="1.0"?>
<SubtitleTracks>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>true</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>1</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
<SubtitleTrack>
<IsNotifying>true</IsNotifying>
<Burned>false</Burned>
<Default>false</Default>
<Forced>false</Forced>
<SourceTrack>
<SourceId>0</SourceId>
<TrackNumber>2</TrackNumber>
<Language>English [VOBSUB]</Language>
<LanguageCode>eng</LanguageCode>
<SubtitleType>VobSub</SubtitleType>
</SourceTrack>
<SrtOffset>0</SrtOffset>
<SubtitleType>VobSub</SubtitleType>
</SubtitleTrack>
</SubtitleTracks>
$xsltproc subtittransform.xslt subtittracks.xml
真的
假的
真的
假的
0
1.
英语[美国之音]
英格
VobSub
0
VobSub
真的
假的
假的
假的
0
2.
英语[美国之音]
英格
VobSub
0
VobSub
注意事项:
在windows上,要通过命令行运行XSLT处理器,请查看:
您对使用CMD批处理文件实现的限制增加了复杂性并降低了性能 批处理文件用于集成和同步程序执行 您的任务更多地是关于文本/xml处理程序 更合适的工具是
perl
/python
/awk
脚本。这些语言是为文本处理而设计的
以下是一个6行awk程序示例:
awk'
pass1&/false/{markedLine=NR}
pass1&/0/{sourceIdFlag=1;next}
pass1&&sourceIdFlag&&1/{markedLinesArr[markedLine]=1}
pass1{sourceIdFlag=0}
!pass1&&markedLinesArr[FNR]==1{print“true”;next}
!pass1{print}
'pass1=1 input.xml pass1=0 input.xml
输出
真的
假的
真的
假的
0
1.
英语[美国之音]
英格
VobSub
0
VobSub
真的
假的
假的
假的
0
2.
英语[美国之音]
英格
VobSub
0
VobSub
Regex是这里使用的错误工具,您考虑过使用XSLT吗?请注意所有进入这里的人。我已经在我的答案中添加了一些注释,您能检查一下它是否适合您吗?我已经使用libxslt-1.1.26.win32进行了尝试。它对文件成功运行,没有任何错误,但我的输出不会像上面为您所做的那样发生更改。默认值仍为false。我错过了什么?@StrangelThings:真奇怪。。。你能用别的工具试试吗?或者甚至直接通过saxon
?@奇怪事物:您需要将命令的输出重定向到一个新文件xsltproc.exe-v subtittransform.xslt subtittracks.xml>new_file.xml
@奇怪事物:您还可以使用选项-o output.xml
来定义要写入输出消息的输出文件“警告:使用旧版本206根据libxml 207编译的程序”