December 16, 2016

Useful XPath

Join Element Text

Input :
<employees>
    <employee>
        <empId>123</empId>
    </employee>
    <employee>
        <empId>456</empId>
    </employee>
</employees>

XPath : string-join(//empId, ',')

Output :
123,456

Distinct Values in XPath 1.0
Distinct function is not available in XPath 2.0. Therefore in XPath 1.0 you have to use the following.

Input :
<students>
<student>
<studentId>100</studentId>
<subject>Maths</subject>
</student>
<student>
<studentId>102</studentId>
<subject>Science</subject>
</student>
<student>
<studentId>101</studentId>
<subject>English</subject>
</student>
<student>
<studentId>100</studentId>
<subject>English</subject>
</student>
<student>
<studentId>100</studentId>
<subject>Science</subject>
</student>
</students>

XPath : //student/studentId[not(.=preceding::*)]

Output :
<result>
   <studentId>100</studentId>
   <studentId>102</studentId>
   <studentId>101</studentId>
</result>

December 2, 2016

XSLT Tips and Tricks

Remove CDATA section from a XML

Input XML
<request><![CDATA[ 
   <user>
     <firstname>Maheeka</firstname>
     <lastname>Jayasuriya</lastname>
   </user>]]>
</request>

XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output indent="yes"/>
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="*:request/text()">
      <xsl:value-of disable-output-escaping="yes" select="."/>
   </xsl:template>
</xsl:stylesheet>

Transformed XML
<request> 
   <user>
      <firstname>Maheeka</firstname>
      <lastname>Jayasuriya</lastname>
   </user>
</request>

Extract Element Names to Element Values

Input XML
<user>
   <FirstName>Maheeka</FirstName>
   <LastName>Jayasuriya</LastName>
   <Age>26</Age>
</user>

XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="//user">
      <user>
         <xsl:for-each select="*">
             <xsl:value-of select="local-name()"/> = <xsl:value-of select="."/>,  
         </xsl:for-each>
      </user>
   </xsl:template>
</xsl:stylesheet>

Transformed XML
<user>FirstName = Maheeka,  
LastName = Jayasuriya,  
Age = 26,  
</user>

Group Payload By a Distinct Value

Input XML
<students>
    <student>
        <studentId>100</studentId>
        <subject>Maths</subject>
    </student>
    <student>
        <studentId>102</studentId>
        <subject>Science</subject>
    </student>
    <student>
        <studentId>101</studentId>
        <subject>English</subject>
    </student>
    <student>
        <studentId>100</studentId>
        <subject>English</subject>
    </student>
    <student>
        <studentId>100</studentId>
        <subject>Science</subject>
    </student>
</students>

XSLT
<xsl:stylesheet version="1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <students>
            <xsl:for-each select="//student/studentId[not(.=preceding::*)]">
                <xsl:variable name="studentId" select="."/>
                <student>
                    <studentId>
                        <xsl:value-of select="$studentId"/>
                    </studentId>
                    <xsl:for-each select="//student[studentId=$studentId]/subject">
                        <subject>
                            <xsl:value-of select="."/>
                        </subject>
                    </xsl:for-each>
                </student>
            </xsl:for-each>
        </students>
    </xsl:template>
</xsl:stylesheet>

Transformed XML
<students xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <student>
        <studentId>100</studentId>
        <subject>Maths</subject>
        <subject>English</subject>
        <subject>Science</subject>
    </student>
    <student>
        <studentId>102</studentId>
        <subject>Science</subject>
    </student>
    <student>
        <studentId>101</studentId>
        <subject>English</subject>
    </student>
</students>