繁体   English   中英

XML 使用 XSL 在基于属性的情况下动态去除线条

[英]XML dynamic line removal in attribute-based using XSL

我有一个复杂且非常大的 xml ,如果行属性小于指定值,我应该搜索每行的最后一层并删除该行(或带有该行的整个石斑鱼)。

例如,下面是 XML 的示例,我必须查看“Op”元素的每一行以查看 DtContrat 属性是否小于“2021-01-01”,如果更小,我应该删除带有“ Op” 元素和任何被它分组的东西,但是,如果父行 (Cli) 只有一个“Op” 元素并且它被删除了,我还必须删除整个“Cli” 元素

<Doc3040 DtBase="2021-11" CNPJ="12345678" TotalCli="3" Remessa="1" Parte="1" TpArq="F" NomeResp="Alexander" EmailResp="alexander@alexander.com.br" TelResp="123456789">
        <Cli Cd="13245678912" Tp="1" Autorzc="N" PorteCli="0" IniRelactCli="2020-09-25" ClassCli="A" FatAnual="0.01">
            <Op Contrt="123456" IPOC="132456789123456789123456789" Mod="0218" Cosif="3096000" OrigemRec="0199" Indx="11" PercIndx="0.00" VarCamb="790" CEP="0000000" TaxEft="790.7188400" DtContr="2020-04-25" NatuOp="01" DtVencOp="2021-04-25" ClassOp="H" DiaAtraso="189" CaracEspecial="19">
                <Inf Tp="0399"/>
            </Op>
            <Op Contrt="123456" IPOC="132456789123456789123456780" Mod="0210" Cosif="3096000" OrigemRec="0199" Indx="11" PercIndx="0.00" VarCamb="790" CEP="0000000" TaxEft="790.7188400" DtContr="2021-05-15" NatuOp="01" DtVencOp="2021-10-25" ClassOp="H" DiaAtraso="189" CaracEspecial="19">
                <Inf Tp="0399"/>
            </Op>
        </Cli>
        <Cli Cd="12345678913" Tp="1" Autorzc="N" PorteCli="0" IniRelactCli="2019-06-27" ClassCli="A" FatAnual="0.01">
            <Op Contrt="123457" IPOC="132456789123456789123456788" Mod="0210" Cosif="1612022" OrigemRec="0199" Indx="11" PercIndx="0.00" VarCamb="790" CEP="88117400" TaxEft="59.9200000" DtContr="2020-09-23" NatuOp="01" DtVencOp="2021-03-10" ClassOp="A" ProvConsttd="1.30" DtaProxParcela="2021-12-10" VlrProxParcela="96.87" QtdParcelas="5">
                <Venc v110="96.87" v140="35.95" v130="34.58" v120="93.52"/>
            </Op>
        </Cli>
        <Cli Cd="12345678914" Tp="1" Autorzc="N" PorteCli="0" IniRelactCli="2019-11-23" ClassCli="A" FatAnual="0.01">
            <Op Contrt="132458" IPOC="132456789123456789123456787" Mod="0204" Cosif="1612020" OrigemRec="0199" Indx="11" PercIndx="0.00" VarCamb="790" CEP="88117400" TaxEft="790.7188400" DtContr="2021-11-10" NatuOp="01" DtVencOp="2021-12-10" ClassOp="A" ProvConsttd="0.00" VlrContr="0.03">
                <Venc v110="0.03"/>
            </Op>
        </Cli>
    </Doc3040>

上述 xml 的预期结果如下

<Doc3040 DtBase="2021-11" CNPJ="12345678" TotalCli="2" Remessa="1" Parte="1" TpArq="F" NomeResp="Alexander" EmailResp="alexander@alexander.com.br" TelResp="123456789">
    <Cli Cd="13245678912" Tp="1" Autorzc="N" PorteCli="0" IniRelactCli="2020-09-25" ClassCli="A" FatAnual="0.01">
        
        <Op Contrt="123456" IPOC="132456789123456789123456780" Mod="0210" Cosif="3096000" OrigemRec="0199" Indx="11" PercIndx="0.00" VarCamb="790" CEP="0000000" TaxEft="790.7188400" DtContr="2021-05-15" NatuOp="01" DtVencOp="2021-10-25" ClassOp="H" DiaAtraso="189" CaracEspecial="19">
            <Inf Tp="0399"/>
        </Op>
    </Cli>
    <Cli Cd="12345678914" Tp="1" Autorzc="N" PorteCli="0" IniRelactCli="2019-11-23" ClassCli="A" FatAnual="0.01">
        <Op Contrt="132458" IPOC="132456789123456789123456787" Mod="0204" Cosif="1612020" OrigemRec="0199" Indx="11" PercIndx="0.00" VarCamb="790" CEP="88117400" TaxEft="790.7188400" DtContr="2021-11-10" NatuOp="01" DtVencOp="2021-12-10" ClassOp="A" ProvConsttd="0.00" VlrContr="0.03">
            <Venc v110="0.03"/>
        </Op>
    </Cli>
</Doc3040>

请注意,在 Doc3040 元素中,我还需要使用文件中的新“Cli”元素总计更新“TotalCli”属性

我研究并看到使用 XSL 可以做到这一点,但我不了解这种语言,有人可以帮我编写这个 XSL 代码吗?

下面是一个使用专用(空)模板修改身份转换的示例,以匹配@DtContr值小于$cutoff-dateOp元素,并匹配没有任何Op@DtrContr值更大的Cli元素比$cutoff-date 由于该模板不生成任何内容,因此它匹配的项目从 output 中排除。 第三个模板与Doc3040/@TotalCli匹配,并生成一个具有相同名称的属性,但该属性计算Op/@DtContr值大于$cutoff-dateCli的数量。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" />
    
  <xsl:param name="cutoff-date" select="'2021-01-01'"/>
    
  <!--this is the identity template that by default copies all content-->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
    
  <!--more specific templates can be used to match certain content and override the default behavior-->
  <xsl:template match="Cli[not(Op[@DtContr gt $cutoff-date])] | Op[@DtContr lt $cutoff-date]"/>

  <xsl:template match="Doc3040/@TotalCli">
    <xsl:attribute name="{name()}" select="count(../Cli[Op/@DtContr gt $cutoff-date])"/>
  </xsl:template>

</xsl:stylesheet>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM