How to convert XML list into comma seperated list
<xsl:for-each select="/ns0:UserId">
<xsl:text>'</xsl:text>
<xsl:value-of select="."/>
<xsl:text>'</xsl:text>
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
Example:
<UserId>1</UserId>
<UserId>2</UserId>
<UserId>3</UserId>
Into
'1','2','3'
How to strip of empty elements from xml
This xslt code work with any XML types, so it could be saved in a common location and used everywhere.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:if test="normalize-space(string(.)) != ''">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
How to find distinct values and group in XSLT
This xslt will groups the xml elements by distinct UserID
<xsl:key name="UserId" match="/ns0:queryResponse/ns0:QueryResults/ns0:records/ns0:UserId/text()"
use="."/>
<xsl:template match="/">
<tns:TransformationResults>
<xsl:for-each select="/ns0:queryResponse/ns0:QueryResults/ns0:records/ns0:UserId/text()[generate-id() = generate-id(key('UserId',.)[1])]">
<tns:User>
<tns:UserId>
<xsl:value-of select="."/>
</tns:UserId>
<xsl:call-template name="getResponsibility">
<xsl:with-param name="UserId" select="."/>
<xsl:with-param name="records" select="/ns0:queryResponse/ns0:QueryResults/ns0:records"/>
</xsl:call-template>
</tns:User>
</xsl:for-each>
</tns:TransformationResults>
</xsl:template>
<xsl:template name="getResponsibility">
<xsl:param name="UserId"/>
<xsl:param name="records"/>
<xsl:for-each select="$records[ns0:UserId/text() = $UserId]">
<tns:Responsibility>
<tns:ResponsibilityId>
<xsl:value-of select="ns0:rId"/>
</tns:ResponsibilityId>
<tns:ResponsibilityName>
<xsl:value-of select="ns0:rName"/>
</tns:ResponsibilityName>
</tns:Responsibility>
</xsl:for-each>
</xsl:template>
Input
<records>
<UserId>1</UserId>
<rId>1001</rId>
<rName>Responsibility1</rName>
</records>
<records>
<UserId>1</UserId>
<rId>1002</rId>
<rName>Responsibility2</rName>
</records>
<records>
<UserId>2</UserId>
<rId>1001</rId>
<rName>Responsibility1</rName>
</records>
<records>
<UserId>2</UserId>
<rId>1002</rId>
<rName>Responsibility2</rName>
</records>
Output
<TransformationResults>
<User>
<UserId>1</UserId>
<Responsibility>
<ResponsibilityId>1001</ResponsibilityId>
<ResponsibilityName>Responsibility1</ResponsibilityName>
</Responsibility>
<Responsibility>
<ResponsibilityId>1002</ResponsibilityId>
<ResponsibilityName>Responsibility2</ResponsibilityName>
</Responsibility>
</User>
<User>
<UserId>2</UserId>
<Responsibility>
<ResponsibilityId>1001</ResponsibilityId>
<ResponsibilityName>Responsibility1</ResponsibilityName>
</Responsibility>
<Responsibility>
<ResponsibilityId>1002</ResponsibilityId>
<ResponsibilityName>Responsibility2</ResponsibilityName>
</Responsibility>
</User>
</TransformationResults>
List out all the XML elements
I needed this for XSD documentation work. Generate a sample XML from the xsd and use that as input to this xslt. It prints out all the elements in xpath format relative to root element.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" />
<xsl:template match="*[not(*)]">
<xsl:text>response</xsl:text>
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="concat('.', substring-after(name(),':'))"/>
<xsl:if test="count(preceding-sibling::*[name() = name(current())]) != 0">
<xsl:value-of select="concat('[', count(preceding-sibling::*[name() = name(current())]) + 1, ']')"/>
</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates select="*"/>
</xsl:template>
</xsl:stylesheet>