Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 根据匹配的文本/参数修改XML中的重复单词/文本?_Regex_Xml_Batch File_Cmd - Fatal编程技术网

Regex 根据匹配的文本/参数修改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>

我有一个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>

真的
假的
假的
假的
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为0TrackNumber为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编译的程序”