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