Home > Software design >  Unable to generate XML file with tag <Document>
Unable to generate XML file with tag <Document>

Time:12-29

I'm trying to generate the csv file from XML file by xslt transformation. The beginning of xml file:

 <?xml version="1.0" encoding="UTF-8"?>
    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <BkToCstmrDbtCdtNtfctn>
    <GrpHdr>
            <MsgId>UPDD2021-12-20-18.26.01.660000</MsgId>
            <CreDtTm>2021-12-20T18:26:01</CreDtTm>
    </GrpHdr>
    ...
</BkToCstmrDbtCdtNtfctn>
    </Document>

The transformation file:

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output indent="yes" method="text"/>
<xsl:variable select="';'" name="delimiter"/>
<xsl:variable name="newline">
<xsl:text> 
</xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:for-each select="BkToCstmrDbtCdtNtfctn/Ntfctn/Ntry/NtryDtls/TxDtls">
    <xsl:value-of select="../../../../GrpHdr/MsgId"/>
    <xsl:value-of select="$delimiter"/>
    <xsl:value-of select="../../../../Ntfctn/CreDtTm"/>
    <xsl:value-of select="$delimiter"/>
    <xsl:value-of select="$newline"/>
</xsl:for-each>
</xsl:template>
</Document>
</xsl:stylesheet>

However the csv file is not generated as it supposed to because it looks like this (each record is on new line):

        UPDD2021-12-20-18.26.01.660000
        2021-12-20T18:26:01
    
    
        003409153772021-12-20-18.26.01.9625
        2021-12-20T18:26:01

When I delete tag Document> from both files it looks correctly (with added ';' and each on one line):

UPDD2021-12-20-18.26.01.660000;2021-12-20T18:26:01;

Does somebody know how to update the transformation file to get the csv looking correctly?

After changing file like below, empty file is generating:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camt="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02"
          exclude-result-prefixes="camt">
<xsl:output indent="yes" method="text"/>
<xsl:variable select="';'" name="delimiter"/>
<xsl:variable name="newline">
<xsl:text> 
</xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:for-each select="camt:BkToCstmrDbtCdtNtfctn/camt:Ntfctn/camt:Ntry/camt:NtryDtls/camt:TxDtls">
    <xsl:value-of select="../../../../camt:GrpHdr/camt:MsgId"/>
    <xsl:value-of select="$delimiter"/>
    <xsl:value-of select="../../../../Ntfctn/CreDtTm"/>
    <xsl:value-of select="$delimiter"/>
<xsl:value-of select="$newline"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

CodePudding user response:

If the </Document> end tag appears at the end of the stylesheet (which you haven't shown us) then all your XSLT code is within a top-level data element, which is equivalent to commenting it out. The result is that you've executed the "null stylesheet" on the source document, which will copy the text nodes from the source document and ignore everything else.

CodePudding user response:

With an XSLT 2 or 3 processor you want to declare e.g. xpath-default-namespace=""urn:iso:std:iso:20022:tech:xsd:camt.054.001.02" on the xsl:stylesheet element and then write paths within the XSLT code where you can use the local element names from the input documents. Any xsl:template needs to be a top-level child of xsl:stylesheet.

For an XSLT 1 processor you need to bind the namespace URI to a prefix in the XSLT (e.g. xmlns:camt="urn:iso:std:iso:20022:tech:xsd:camt.054.001.02") and use that prefix to qualify any element names in path expressions.

  • Related