简体   繁体   中英

Convert XML to HTML using xslt

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>

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM