Reputation: 21
I developed a java based command line utility that transform an xml into another xml file and generate HTML. In this program I used SAX parser to read the content of source xml into my java object then use JAXB to generate the XML. Right now I'm creating the HTMl file by populating a string for HTML content but it results in hardcoded html codes inside my java class. Based on my research I can do XML to HTML conversion using XSLT. I am new to XSLT. Can anyone help me? Please see samples below. Thanks
XML input:
<Groups>
<Group>
<GroupName>GroupA</GroupName>
<Role>
<RoleName>Correspondence Team B</RoleName>
<Functions>
<Function>CT2 Work</Function>
<Function>HOL01_My Work</Function>
<Function>HOL02_My Work</Function>
</Functions>
</Role>
</Group>
<GroupName>GroupB</GroupName>
<Role>
<RoleName>Customer Service Rep</RoleName>
<Functions>
<Function>CSR Work</Function>
<Function>HOL01_My Work</Function>
</Functions>
</Role>
</Group>
<Group>
<GroupName>GroupB</GroupName>
<Role>
<RoleName>Dispute Advisor</RoleName>
<Functions>
<Function>DA Work</Function>
<Function>HOL01_My Work</Function>
</Functions>
</Role>
</Group>
<Group>
<GroupName>GroupA</GroupName>
<Role>
<RoleName>Correspondence Team</RoleName>
<Functions>
<Function>CT Work</Function>
<Function>HOL01_My Work</Function>
</Functions>
</Role>
</Group>
<Group>
<GroupName>GroupB</GroupName>
<Role>
<RoleName>Correspondence Team B</RoleName>
<Functions>
<Function>CT2 Work</Function>
<Function>HOL01_My Work</Function>
<Function>HOL02_My Work</Function>
</Functions>
</Role>
</Group>
Desired Html table format:
<table border=1>
<tr>
<th>Group Name</th>
<th>Role Name</th>
<th>Function Names</th>
</tr>
<tr>
<td rowspan=5>Group A</td>
<td rowspan=2>Correspondence Team</td>
<td>CT Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<td rowspan=3>Correspondence Team B</td>
<td>CT Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<td rowspan=0>Group B</td>
<td rowspan=2>Customer Service Rep</td>
<td>CSR Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<td rowspan=2>Dispute Advisor</td>
<td>DA Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<td rowspan=2>Correspondence Team</td>
<td>CT Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
</table>
Upvotes: 1
Views: 18049
Reputation: 167516
Assuming XSLT 2.0 (which you can run with Java with the help of Saxon 9) you can use a stylesheet like
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="html" indent="yes" version="5.0"/>
<xsl:template match="/">
<html lang="en">
<head>
<title>Test</title>
</head>
<body>
<h1>Test</h1>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="Groups">
<table frame="border" rules="all">
<thead>
<th>Group Name</th>
<th>Role Name</th>
<th>Function Names</th>
</thead>
<tbody>
<xsl:variable name="groups" as="element(group)*">
<xsl:for-each-group select="Group" group-by="GroupName">
<group name="{current-grouping-key()}" size="{count(current-group()/Role/Functions/Function)}">
<xsl:for-each-group select="current-group()" group-by="Role/RoleName">
<role name="{current-grouping-key()}" size="{count(current-group()/Role/Functions/Function)}">
<xsl:copy-of select="current-group()/Role/Functions/Function"/>
</role>
</xsl:for-each-group>
</group>
</xsl:for-each-group>
</xsl:variable>
<xsl:apply-templates select="$groups/role/Function"/>
</tbody>
</table>
</xsl:template>
<xsl:template match="group/role/Function">
<tr>
<xsl:apply-templates select="." mode="group"/>
<xsl:apply-templates select="." mode="role"/>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:template>
<xsl:template match="group/role[1]/Function[1]" mode="group">
<th rowspan="{../../@size}">
<xsl:value-of select="../../@name"/>
</th>
</xsl:template>
<xsl:template match="group/role[position() gt 1]/Function |
group/role[1]/Function[position() gt 1]" mode="group"/>
<xsl:template match="group/role/Function[1]" mode="role">
<th rowspan="{../@size}">
<xsl:value-of select="../@name"/>
</th>
</xsl:template>
<xsl:template match="group/role/Function[position() gt 1]" mode="role"/>
</xsl:stylesheet>
to transform an input document like
<Groups>
<Group>
<GroupName>GroupA</GroupName>
<Role>
<RoleName>Correspondence Team B</RoleName>
<Functions>
<Function>CT2 Work</Function>
<Function>HOL01_My Work</Function>
<Function>HOL02_My Work</Function>
</Functions>
</Role>
</Group>
<Group>
<GroupName>GroupB</GroupName>
<Role>
<RoleName>Customer Service Rep</RoleName>
<Functions>
<Function>CSR Work</Function>
<Function>HOL01_My Work</Function>
</Functions>
</Role>
</Group>
<Group>
<GroupName>GroupB</GroupName>
<Role>
<RoleName>Dispute Advisor</RoleName>
<Functions>
<Function>DA Work</Function>
<Function>HOL01_My Work</Function>
</Functions>
</Role>
</Group>
<Group>
<GroupName>GroupA</GroupName>
<Role>
<RoleName>Correspondence Team</RoleName>
<Functions>
<Function>CT Work</Function>
<Function>HOL01_My Work</Function>
</Functions>
</Role>
</Group>
<Group>
<GroupName>GroupB</GroupName>
<Role>
<RoleName>Correspondence Team B</RoleName>
<Functions>
<Function>CT2 Work</Function>
<Function>HOL01_My Work</Function>
<Function>HOL02_My Work</Function>
</Functions>
</Role>
</Group>
</Groups>
into HTML5 like
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
</head>
<body>
<h1>Test</h1>
<table frame="border" rules="all">
<thead>
<th>Group Name</th>
<th>Role Name</th>
<th>Function Names</th>
</thead>
<tbody>
<tr>
<th rowspan="5">GroupA</th>
<th rowspan="3">Correspondence Team B</th>
<td>CT2 Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<td>HOL02_My Work</td>
</tr>
<tr>
<th rowspan="2">Correspondence Team</th>
<td>CT Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<th rowspan="7">GroupB</th>
<th rowspan="2">Customer Service Rep</th>
<td>CSR Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<th rowspan="2">Dispute Advisor</th>
<td>DA Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<th rowspan="3">Correspondence Team B</th>
<td>CT2 Work</td>
</tr>
<tr>
<td>HOL01_My Work</td>
</tr>
<tr>
<td>HOL02_My Work</td>
</tr>
</tbody>
</table>
</body>
</html>
Upvotes: 4