首页 > 解决方案 > 如何删除 XML 中的重复数据或按值分组在嵌套标记中使用 XSLT

问题描述

我正在尝试使用 XSLT 1.0 对 XML 中的元素进行分组。

我想从 XML 中删除重复的数据:具体来说,我想删除在输入 XML 中重复的 Dbtr、DbtrAcct、DbtrAgt、ChrgBr 标记。

我的输入 XML 是:...

<?xml version="1.0" encoding="utf-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <CstmrCdtTrfInitn>
    <GrpHdr>
      <MsgId>USB0003108</MsgId>
      <CreDtTm>2021-07-07T10:48:26</CreDtTm>
      <Authstn>
        <Cd>FDET</Cd>
      </Authstn>
      <NbOfTxs>2</NbOfTxs>
      <CtrlSum>89698.68</CtrlSum>
      <InitgPty>
        <Id>
          <OrgId>
            <Othr>
              <Id>ABC56830001</Id>
            </Othr>
          </OrgId>
        </Id>
      </InitgPty>
    </GrpHdr>
    <PmtInf>
      <PmtInfId>5637145358</PmtInfId>
      <PmtMtd>TRF</PmtMtd>
      <PmtTpInf>
        <SvcLvl>
          <Cd>URGP</Cd>
        </SvcLvl>
      </PmtTpInf>
      <Dbtr>
        <Nm>JJJ Group Inc</Nm>
        <PstlAdr>
          <StrtNm>Street</StrtNm>
          <PstCd>60090</PstCd>
          <TwnNm>Lake Forest</TwnNm>
          <CtrySubDvsn>IL</CtrySubDvsn>
          <Ctry>US</Ctry>
        </PstlAdr>
      </Dbtr>
    </PmtInf>
    <DbtrAcct>
      <Id>
        <Othr>
          <Id>000198588</Id>
        </Othr>
      </Id>
    </DbtrAcct>
    <DbtrAgt>
      <FinInstnId>
        <BIC>MRMDUS33</BIC>
        <ClrSysMmbId>
          <MmbId>021001088</MmbId>
        </ClrSysMmbId>
        <PstlAdr>
          <Ctry>US</Ctry>
        </PstlAdr>
      </FinInstnId>
    </DbtrAgt>
    <ChrgBr>DEBT</ChrgBr>
    <CdtTrfTxInf>
      <PmtId>
        <InstrId>USPP-000000014</InstrId>
        <EndToEndId>USPP-000000014</EndToEndId>
      </PmtId>
      <Amt>
        <InstdAmt Ccy="USD">13236.00</InstdAmt>
      </Amt>
      <CdtrAgt>
        <FinInstnId>
          <BIC>TEST8765</BIC>
          <PstlAdr>
            <Ctry>US</Ctry>
          </PstlAdr>
        </FinInstnId>
      </CdtrAgt>
      <Cdtr>
        <Nm>CDTR1</Nm>
        <PstlAdr>
          <StrtNm>PO BOX </StrtNm>
          <PstCd>15293</PstCd>
          <TwnNm>TWN</TwnNm>
          <CtrySubDvsn>PA</CtrySubDvsn>
          <Ctry>US</Ctry>
        </PstlAdr>
      </Cdtr>
      <CdtrAcct>
        <Id>
          <Othr>
            <Id>CDTRID</Id>
          </Othr>
        </Id>
      </CdtrAcct>
    </CdtTrfTxInf>
    <PmtInf>
      <PmtInfId>5637145358</PmtInfId>
      <PmtMtd>TRF</PmtMtd>
      <PmtTpInf>
        <SvcLvl>
          <Cd>URGP</Cd>
        </SvcLvl>
      </PmtTpInf>
      <Dbtr>
        <Nm>JJJ Group Inc</Nm>
        <PstlAdr>
          <StrtNm>Street</StrtNm>
          <PstCd>60090</PstCd>
          <TwnNm>Lake Forest</TwnNm>
          <CtrySubDvsn>IL</CtrySubDvsn>
          <Ctry>US</Ctry>
        </PstlAdr>
      </Dbtr>
    </PmtInf>
    <DbtrAcct>
      <Id>
        <Othr>
          <Id>000198588</Id>
        </Othr>
      </Id>
    </DbtrAcct>
    <DbtrAgt>
      <FinInstnId>
        <BIC>MRMDUS33</BIC>
        <ClrSysMmbId>
          <MmbId>021001088</MmbId>
        </ClrSysMmbId>
        <PstlAdr>
          <Ctry>US</Ctry>
        </PstlAdr>
      </FinInstnId>
    </DbtrAgt>
    <ChrgBr>DEBT</ChrgBr>
    <CdtTrfTxInf>
      <PmtId>
        <InstrId>USPP-000000015</InstrId>
        <EndToEndId>USPP-000000015</EndToEndId>
      </PmtId>
      <Amt>
        <InstdAmt Ccy="USD">76462.68</InstdAmt>
      </Amt>
      <CdtrAgt>
        <FinInstnId>
          <BIC>TEST29834</BIC>
          <PstlAdr>
            <Ctry>US</Ctry>
          </PstlAdr>
        </FinInstnId>
      </CdtrAgt>
      <Cdtr>
        <Nm>CDTR NM</Nm>
        <PstlAdr>
          <StrtNm>CDTR STRT</StrtNm>
          <PstCd>43230</PstCd>
          <TwnNm>Columbus</TwnNm>
          <CtrySubDvsn>OH</CtrySubDvsn>
          <Ctry>US</Ctry>
        </PstlAdr>
      </Cdtr>
      <CdtrAcct>
        <Id>
          <Othr>
            <Id>0189830ABCD</Id>
          </Othr>
        </Id>
      </CdtrAcct>
    </CdtTrfTxInf>
  </CstmrCdtTrfInitn>
</Document>

...

所需的输出是:...

<?xml version="1.0" encoding="utf-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <CstmrCdtTrfInitn>
    <GrpHdr>
      <MsgId>USB0003108</MsgId>
      <CreDtTm>2021-07-07T10:48:26</CreDtTm>
      <Authstn>
        <Cd>FDET</Cd>
      </Authstn>
      <NbOfTxs>2</NbOfTxs>
      <CtrlSum>89698.68</CtrlSum>
      <InitgPty>
        <Id>
          <OrgId>
            <Othr>
              <Id>ABC56830001</Id>
            </Othr>
          </OrgId>
        </Id>
      </InitgPty>
    </GrpHdr>
    <PmtInf>
      <PmtInfId>5637145358</PmtInfId>
      <PmtMtd>TRF</PmtMtd>
      <PmtTpInf>
        <SvcLvl>
          <Cd>URGP</Cd>
        </SvcLvl>
      </PmtTpInf>
      <Dbtr>
        <Nm>JJJ Group Inc</Nm>
        <PstlAdr>
          <StrtNm>Street</StrtNm>
          <PstCd>60090</PstCd>
          <TwnNm>Lake Forest</TwnNm>
          <CtrySubDvsn>IL</CtrySubDvsn>
          <Ctry>US</Ctry>
        </PstlAdr>
      </Dbtr>
    </PmtInf>
    <DbtrAcct>
      <Id>
        <Othr>
          <Id>000198588</Id>
        </Othr>
      </Id>
    </DbtrAcct>
    <DbtrAgt>
      <FinInstnId>
        <BIC>MRMDUS33</BIC>
        <ClrSysMmbId>
          <MmbId>021001088</MmbId>
        </ClrSysMmbId>
        <PstlAdr>
          <Ctry>US</Ctry>
        </PstlAdr>
      </FinInstnId>
    </DbtrAgt>
    <ChrgBr>DEBT</ChrgBr>
    <CdtTrfTxInf>
      <PmtId>
        <InstrId>USPP-000000014</InstrId>
        <EndToEndId>USPP-000000014</EndToEndId>
      </PmtId>
      <Amt>
        <InstdAmt Ccy="USD">13236.00</InstdAmt>
      </Amt>
      <CdtrAgt>
        <FinInstnId>
          <BIC>TEST8765</BIC>
          <PstlAdr>
            <Ctry>US</Ctry>
          </PstlAdr>
        </FinInstnId>
      </CdtrAgt>
      <Cdtr>
        <Nm>CDTR1</Nm>
        <PstlAdr>
          <StrtNm>PO BOX </StrtNm>
          <PstCd>15293</PstCd>
          <TwnNm>TWN</TwnNm>
          <CtrySubDvsn>PA</CtrySubDvsn>
          <Ctry>US</Ctry>
        </PstlAdr>
      </Cdtr>
      <CdtrAcct>
        <Id>
          <Othr>
            <Id>CDTRID</Id>
          </Othr>
        </Id>
      </CdtrAcct>
    </CdtTrfTxInf>
    <PmtInf>
      <PmtInfId>5637145358</PmtInfId>
      <PmtMtd>TRF</PmtMtd>
      <PmtTpInf>
        <SvcLvl>
          <Cd>URGP</Cd>
        </SvcLvl>
      </PmtTpInf>
    </PmtInf>
    <CdtTrfTxInf>
      <PmtId>
        <InstrId>USPP-000000015</InstrId>
        <EndToEndId>USPP-000000015</EndToEndId>
      </PmtId>
      <Amt>
        <InstdAmt Ccy="USD">76462.68</InstdAmt>
      </Amt>
      <CdtrAgt>
        <FinInstnId>
          <BIC>TEST29834</BIC>
          <PstlAdr>
            <Ctry>US</Ctry>
          </PstlAdr>
        </FinInstnId>
      </CdtrAgt>
      <Cdtr>
        <Nm>CDTR NM</Nm>
        <PstlAdr>
          <StrtNm>CDTR STRT</StrtNm>
          <PstCd>43230</PstCd>
          <TwnNm>Columbus</TwnNm>
          <CtrySubDvsn>OH</CtrySubDvsn>
          <Ctry>US</Ctry>
        </PstlAdr>
      </Cdtr>
      <CdtrAcct>
        <Id>
          <Othr>
            <Id>0189830ABCD</Id>
          </Othr>
        </Id>
      </CdtrAcct>
    </CdtTrfTxInf>
  </CstmrCdtTrfInitn>
</Document>

...

我正在尝试的 XSLT 如下,但我无法达到预期的结果:

...

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="PmtInfByDbtrNm" match="ns1:Dbtr" use="ns1:Nm" />
<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="ns1:CstmrCdtTrfInitn">
    <xsl:copy>
        <xsl:copy-of select="ns1:GrpHdr"/>
        <xsl:copy-of select="ns1:PmtInf"/>
        
        <xsl:for-each select="ns1:Dbtr[count(. | key('PmtInfByDbtrNm', ns1:Nm)[1]) = 1]">
            <xsl:copy>
               
                <xsl:copy-of select="ns1:PmtInfId | ns1:PmtMtd | ns1:PmtTpInf | ns1:ReqdExctnDt | ns1:Dbtr | ns1:DbtrAcct | ns1:DbtrAgt | ns1:ChrgBr"/>
                
                <xsl:for-each select="key('PmtInfByDbtrNm', ns1:PmtInfId)">
                    <xsl:copy-of select="ns1:CdtTrfTxInf"/>
                </xsl:for-each>
            </xsl:copy> 
        </xsl:for-each>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

...

谁能告诉我我在哪里失踪或提供一些意见来实现这一目标?

标签: xmlnestedduplicatesgrouping

解决方案


推荐阅读