【问题标题】:How to get nested nodes from XML to CSV via XSLT如何通过 XSLT 将嵌套节点从 XML 获取到 CSV
【发布时间】:2020-05-18 05:58:45
【问题描述】:

我有如下的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.microsoft.com/dynamics/2011/01/documents/Message">
   <Header>
      <MessageId>{70BF3A9B-9111-48D8-93B4-C6232E74307F}</MessageId>
      <Action>http://tempuri.org/example/find</Action>
   </Header>
   <Body>
      <MessageParts>
         <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <pain.001.001.02>
               <GrpHdr>
                  <MsgId>AB01029407</MsgId>
                  <CreDtTm>2020-05-07T11:23:08</CreDtTm>
                  <NbOfTxs>2</NbOfTxs>
                  <CtrlSum>4598</CtrlSum>
                  <Grpg>MIXD</Grpg>
                  <InitgPty>
                     <Nm>MY COMPANY Ltd1</Nm>
                     <Id>
                        <OrgId>
                           <TaxIdNb>GB 823825133</TaxIdNb>
                        </OrgId>
                     </Id>
                  </InitgPty>
               </GrpHdr>
               <PmtInf>
                  <PmtInfId>AB01029407</PmtInfId>
                  <PmtMtd>TRF</PmtMtd>
                  <PmtTpInf>
                     <SvcLvl>
                        <Cd>SEPA</Cd>
                     </SvcLvl>
                  </PmtTpInf>
                  <Dbtr>
                     <Nm>MY COMPANY Ltd</Nm>
                     <PstlAdr>
                        <AdrLine>Address Line 1</AdrLine>
                        <AdrLine>Address Line 2</AdrLine>
                        <Ctry>CB</Ctry>
                     </PstlAdr>
                  </Dbtr>
                  <DbtrAcct>
                     <Id>
                        <IBAN>98</IBAN>
                     </Id>
                  </DbtrAcct>
                  <DbtrAgt>
                     <FinInstnId>
                        <BIC>ABC123</BIC>
                     </FinInstnId>
                  </DbtrAgt>
                  <ChrgBr>SLEV</ChrgBr>
                  <CdtTrfTxInf>
                     <PmtId>
                        <EndToEndId>Not-Provided</EndToEndId>
                     </PmtId>
                     <Amt>
                        <InstdAmt Ccy="CAD">2198.00</InstdAmt>
                     </Amt>
                     <CdtrAgt>
                        <FinInstnId>
                           <BIC>SWIFT01</BIC>
                        </FinInstnId>
                     </CdtrAgt>
                     <Cdtr>
                        <Nm>Creditor Name</Nm>
                        <PstlAdr>
                           <AdrLine>tests</AdrLine>
                           <AdrLine>Chicago</AdrLine>
                           <Ctry>US</Ctry>
                        </PstlAdr>
                     </Cdtr>
                     <CdtrAcct>
                        <Id>
                           <IBAN>98</IBAN>
                        </Id>
                     </CdtrAcct>
                     <RmtInf>
                        <Ustrd>1345</Ustrd>
                     </RmtInf>
                  </CdtTrfTxInf>
                  <CdtTrfTxInf>
                     <PmtId>
                        <EndToEndId>Not-Provided</EndToEndId>
                     </PmtId>
                     <Amt>
                        <InstdAmt Ccy="EUR">2400.00</InstdAmt>
                     </Amt>
                     <CdtrAgt>
                        <FinInstnId>
                           <BIC>SWIFT01</BIC>
                        </FinInstnId>
                     </CdtrAgt>
                     <Cdtr>
                        <Nm>Creditor Name1</Nm>
                        <PstlAdr>
                           <AdrLine>tests</AdrLine>
                           <AdrLine>Chicago</AdrLine>
                           <Ctry>US</Ctry>
                        </PstlAdr>
                     </Cdtr>
                     <CdtrAcct>
                        <Id>
                           <IBAN>98</IBAN>
                        </Id>
                     </CdtrAcct>
                     <RmtInf>
                        <Ustrd>123456765</Ustrd>
                     </RmtInf>
                  </CdtTrfTxInf>
               </PmtInf>
            </pain.001.001.02>
         </Document>
      </MessageParts>
   </Body>
</Envelope>

我有这样的 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ns1="http://schemas.microsoft.com/dynamics/2011/01/documents/Message"
    xmlns:ns2="urn:iso:std:iso:20022:tech:xsd:pain.001.001.02"
    version="1.0">
  <xsl:output method="text"/>  
<xsl:template match="/">
    <xsl:apply-templates
    select="ns1:Envelope/ns1:Body//ns2:pain.001.001.02//ns2:GrpHdr"/>
    </xsl:template>
  <xsl:template match="ns2:GrpHdr">
      <xsl:value-of select="ns2:CreDtTm"/>
      <xsl:text>,</xsl:text>
      <xsl:value-of select="ns2:NbOfTxs"/>
      <xsl:text>,</xsl:text>
      <xsl:value-of select="ns2:CtrlSum"/>
      <xsl:text>,</xsl:text>
      <xsl:value-of select="ns2:Grpg"/>
      <xsl:text>,</xsl:text>
      <xsl:value-of select="ns2:InitgPty/Nm"/>
  <xsl:text>&#xa;</xsl:text> <!-- Line Return -->
  </xsl:template>
  </xsl:stylesheet>

有了这个 XSLT,我只得到一组..但不能超越一组元素。我得到的输出是:

2020-05-07T11:23:08,2,4598,MIXD,

这看起来只是正确的。但我想要几乎所有特定的节点。我无法从模板中获取内部嵌套元素。

想要的输出是:

2020-05-07T11:23:08,2,4598,MIXD,MY COMPANY Ltd1,GB 823825133,AB01029407,TRF,SEPA,MY COMPANY Ltd,Address Line 1,Address Line 2,CB,98,ABC123,SLEV,Not-Provided,2198.00,SWIFT01,Creditor Name,tests,Chicago,US,98,1345
2020-05-07T11:23:08,2,4598,MIXD,MY COMPANY Ltd1,GB 823825133,AB01029407,TRF,SEPA,MY COMPANY Ltd,Address Line 1,Address Line 2,CB,98,ABC123,SLEV,Not-Provided,2400.00,SWIFT01,Creditor Name1,tests,Chicago,US,98,123456765

我是 XSLT 的新手。有人能帮忙吗 ? 提前致谢。

【问题讨论】:

    标签: for-loop templates xslt nested tags


    【解决方案1】:

    试试这个作为你的起点:

    XSLT 1.0

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns1="http://schemas.microsoft.com/dynamics/2011/01/documents/Message"
    xmlns:ns2="urn:iso:std:iso:20022:tech:xsd:pain.001.001.02">
    <xsl:output method="text"/>  
    
    <xsl:template match="/ns1:Envelope">
        <!-- data from header -->
        <xsl:variable name="header" select="ns1:Body/ns1:MessageParts/ns2:Document/ns2:pain.001.001.02/ns2:GrpHdr" />
        <xsl:value-of select="$header/ns2:CreDtTm"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$header/ns2:NbOfTxs"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$header/ns2:CtrlSum"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$header/ns2:Grpg"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$header/ns2:InitgPty/ns2:Nm"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$header/ns2:InitgPty/ns2:Id/ns2:OrgId/ns2:TaxIdNb"/>
        <xsl:text>,</xsl:text>
        <!-- data from pmt -->
        <xsl:variable name="pmt" select="ns1:Body/ns1:MessageParts/ns2:Document/ns2:pain.001.001.02/ns2:PmtInf" />
        <xsl:value-of select="$pmt/ns2:PmtMtd"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$pmt/ns2:Dbtr/ns2:Nm"/>
        <xsl:text>,</xsl:text>
        <!-- CONTINUE HERE -->
    </xsl:template>
    
    </xsl:stylesheet>
    

    请注意,这假设输入 XML 中只有一条记录,因此输出 CSV 中只有一行。您的 XML 的结构方式允许在层次结构的不同级别上存在多个相同类型的节点。如果您想在 CSV 中反映这一点,您需要决定哪个节点将代表一条记录并调整样式表,以便它为此类节点的每个实例创建一个单独的行 - 请参见此处的示例:https://stackoverflow.com/a/55311500/3016153

    【讨论】:

    • 谢谢@Michael。我刚才没有尝试这样: 我得到了这个:2020-05-07T11:23:08,2 ,4598,MIXD,MY COMPANY Ltd1, GB 823825133 尚未按预期构建。同时,我从您那里得到了解决方案.. 一个真正伟大而快速的答复。谢谢。
    • 嗨@Michael,您能告诉我根据 CdtTrfTxInf 循环它吗?我想循环 CdtTrfTxInf 并显示所有数据以及 GrpHdr 和 Dbtr 信息。所需:2020-05-07T11:23:08,2,4598,MIXD,MY COMPANY Ltd1,GB 823825133,AB01029407,TRF,SEPA,MY COMPANY Ltd,Address Line 1,Address Line 2,CB,98,ABC123,SLEV ,未提供,2198.00,SWIFT01,Creditor Name,tests,Chicago,US,98,1345 2020-05-07T11:23:08,2,4598,MIXD,MY COMPANY Ltd1,GB 823825133,AB01029407,TRF,SEPA, MY COMPANY Ltd,Address Line 1,Address Line 2,CB,98,ABC123,SLEV,Not-Provided,2400.00,SWIFT01,Creditor Name1,tests,Chicago,US,98,123456765
    • 请不要在 cmets 中发布代码。编辑您的问题,或者 - 最好,因为这是一个新要求 - 发布一个新问题。请注意,我上面提供的链接显示了类似问题的解决方案;在寻求帮助之前,请尝试使其适应您的情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多