根据匹配的文本/参数修改XML中的重复单词/文本?

时间:2019-05-22 02:01:23

标签: regex xml batch-file cmd

我有一个XML文件,其中包含以下内容:

SELECT COUNT(*), home_number, agent_no FROM user_data 
WHERE agent_no = 70 GROUP BY home_number, agent_no HAVING COUNT(*) > 1

<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> 部分在整个文件中可以重复多次。

但是结构始终是完全相同的。本节中唯一更改的是:

<SubtitleTrack>

那么下一个将是:

<SourceId>0</SourceId>
<TrackNumber>1</TrackNumber>

以此类推...

现在,<SourceId>0</SourceId> <TrackNumber>2</TrackNumber> 总是这样。

我想做的是,当 SourceId为0 并且 TrackNumber为1 时,将<Default>false</Default>更改为<Default>false</Default>仅 strong>。

任何人都可以帮助将这些要求转换为批处理文件吗?

编辑:我想我已经几乎了,但是这很令人窒息,因为我不断得到的结果是<Default>true</Default>

<Default>false</Default> false

2 个答案:

答案 0 :(得分:2)

输入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>

注释:

  

在要通过命令行运行XSLT处理器的Windows上,请查看:   Are there any XSLT processing command line tools?

答案 1 :(得分:1)

您要使用CMD批处理文件实施的限制会增加复杂性并降低性能。

批处理文件用于集成和同步程序执行。

您的任务更多是关于text / xml处理程序的。

更合适的工具是perl / python / awk脚本。这些语言是专为文本处理而设计的。

这是一个示例的6行awk程序:

awk '
pass1 && /<Default>false<\/Default>/ {markedLine = NR} 
pass1 && /<SourceId>0<\/SourceId>/ {sourceIdFlag = 1; next}
pass1 && sourceIdFlag && /<TrackNumber>1<\/TrackNumber>/ {markedLinesArr[markedLine] = 1}
pass1 {sourceIdFlag = 0}
!pass1 && markedLinesArr[FNR] == 1 {print "      <Default>true</Default>";next}
!pass1 {print}
' pass1=1 input.xml pass1=0 input.xml

输出

  <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>