Reputation: 21
I need some help with an XSLT code which I am trying to build. The below XML code has multiple child nodes which I need to transform to a concatenated value of 'variable'_(Filename value). My sample XML is below,
<Attachments>
<AttachFile>
<FilContentType>application/pdf; name=docxyz1.pdf</FilContentType>
<FileName>docxyz1.pdf</FileName>
</AttachFile>
<AttachFile>
<FilContentType>application/pdf;name=docxyz2.pdf</FilContentType>
<FileName>docxyz2.pdf</FileName>
</AttachFile>
<AttachFile>
<FilContentType>application/pdf; name=docxyz3.pdf</FilContentType>
<FileName>docxyz3.pdf.pdf</FileName>
</AttachFile>
</Attachments>
The transformed output needs to be as below
<Attachments>
<AttachFile>
<FilContentType>application/pdf; name=docxyz1.pdf</FilContentType>
<FileName>1_docxyz1.pdf</FileName>
</AttachFile>
<AttachFile>
<FilContentType>application/pdf;name=docxyz2.pdf</FilContentType>
<FileName>2_docxyz2.pdf</FileName>
</AttachFile>
<AttachFile>
<FilContentType>application/pdf; name=docxyz3.pdf</FilContentType>
<FileName>3_docxyz3.pdf.pdf</FileName>
</AttachFile>
</Attachments>
I tried calling a template and using for-each but my logic is incorrect. My XSLT code is below:
<xsl:variable name="Count" select="count(/Attachments/AttachFile/FileName)"/>
<xsl:variable name="i" select="1"></xsl:variable>
<xsl:template match="/">
<xsl:apply-templates select="Attachments"/>
</xsl:template>
<xsl:template match="Attachments">
<Attachments>
<xsl:for-each select="./Attachments/AttachFile">
<AttachFile>
<FilContentType><xsl:value-of select="FilContentType"/></FilContentType>
<xsl:call-template name="Increment">
<xsl:with-param name="i" select="1"/>
<xsl:with-param name="Count" select="$Count"/>
</xsl:call-template>
</AttachFile>
</xsl:for-each>
</Attachments>
</xsl:template>
<xsl:template name="Increment">
<xsl:param name="i"/>
<xsl:param name="Count"/>
<xsl:if test="$Count > $i">
<Filename>
<xsl:value-of select="concat($i,'_',FileName)"/>
</Filename>
<xsl:call-template name="Increment">
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="Count" select="$Count"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Thanks
Upvotes: 2
Views: 117
Reputation: 117165
Couldn't it be simply:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="FileName">
<xsl:copy>
<xsl:number count="AttachFile" format="1_"/>
<xsl:value-of select="." />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Applied to your example, the result will be:
Result
<?xml version="1.0" encoding="utf-16"?>
<Attachments>
<AttachFile>
<FilContentType>application/pdf; name=docxyz1.pdf</FilContentType>
<FileName>1_docxyz1.pdf</FileName>
</AttachFile>
<AttachFile>
<FilContentType>application/pdf;name=docxyz2.pdf</FilContentType>
<FileName>2_docxyz2.pdf</FileName>
</AttachFile>
<AttachFile>
<FilContentType>application/pdf; name=docxyz3.pdf</FilContentType>
<FileName>3_docxyz3.pdf.pdf</FileName>
</AttachFile>
</Attachments>
Demo: https://xsltfiddle.liberty-development.net/bFN1y9y
Upvotes: 2