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?
Problem resolved. Correct transformation:
<?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:Document/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="../../../../camt:Ntfctn/camt:CreDtTm"/>
<xsl:value-of select="$delimiter"/>
<xsl:value-of select="$newline"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
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.