I am trying to create a generic XSLT that will work with multiple types of queries. I found an XSLT format that seems to work for everything I need, except looping to the next user. Within the program that I am using, a query is created and it puts out XML. That XML creates a table with the labels at the top and all the information following in the correct columns. This information includes Guest, Access Type, and Access Type Description. Except I don't want the Guest ID inside of the table, I want it on the top of the table with only Access Type and Access Description inside the table. And I want the XSLT to create a new table for each guest listed. That is where I am running into the problem. I tried to create a variable and I tried Muenchian grouping but I can't seem to get it figured out. I was also wondering if I set up the title incorrectly for the table? I can also only use Version 1.0 of XSLT.
XML
<query xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" numrows="2" queryname="EXAMPLE_GUEST_VIEW" xsi:noNamespaceSchemaLocation="">
<row rownumber="1">
<GUEST_USERID>
<![CDATA[ ID#1 ]]>
</GUEST_USERID>
<GUEST_NAME>
<![CDATA[ ID#1 - User Name 1 ]]>
</GUEST_NAME>
<ACCESS_TYPE>
<![CDATA[ Access Type Name ]]>
</ACCESS_TYPE>
<ACCESS_DESCRIPTION>
<![CDATA[ Access Type Description. ]]>
</ACCESS_DESCRIPTION>
</row>
<row rownumber="2">
<GUEST_USERID>
<![CDATA[ ID#2 ]]>
</GUEST_USERID>
<GUEST_NAME>
<![CDATA[ ID#2 - User Name 2 ]]>
</GUEST_NAME>
<ACCESS_TYPE>
<![CDATA[ Access Type Name ]]>
</ACCESS_TYPE>
<ACCESS_DESCRIPTION>
<![CDATA[ Access Type Description. ]]>
</ACCESS_DESCRIPTION>
</row>
</query>
XSLT
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<div>
<xsl:apply-templates select="Scroll0"/>
</div>
</xsl:template>
<xsl:template match="Scroll0">
<xsl:choose>
<xsl:when test="count(Row) > 0">
<table class="{@class}">
<xsl:if test="@class != ''">
<span><strong><xsl:value-of select="Row[1]/Field2"/></strong></span>
</xsl:if>
<tr><xsl:apply-templates select="Row[1]/*[position() > 1]" mode="headers"/></tr>
<xsl:apply-templates select="Row"/>
</table>
</xsl:when>
<xsl:otherwise>
<div class="alert alert-info">No Guest Listed</div>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="Row/*" mode="headers">
<th id="{local-name(.)}" class="{@class}">
<xsl:choose><xsl:when test="@label != ''"><xsl:value-of select="@label"/></xsl:when><xsl:otherwise><xsl:value-of select="local-name(.)"/></xsl:otherwise></xsl:choose>
</th>
</xsl:template>
<xsl:template match="Row">
<tr>
<xsl:apply-templates select="*[position() > 1]"/>
</tr>
</xsl:template>
<xsl:template match="Row/*">
<td headers="{local-name(.)}" class="{@class}">
<xsl:choose><xsl:when test=". != ''"><xsl:value-of select="."/></xsl:when><xsl:otherwise> </xsl:otherwise></xsl:choose>
</td>
</xsl:template>
</xsl:stylesheet>
Final XML Output
<?xml version="1.0"?>
<div>
<table class="table table-condensed table-hover">
<span><strong> ID#1 - User Name 1</strong></span>
<tr>
<th class="" id="Field3">Access Type</th>
<th class="" id="Field4">Description</th>
</tr>
<tr>
<td class="" headers="Field3"> Access Type Name </td>
<td class="" headers="Field4"> Access type description. </td>
</tr>
<tr>
<td class="" headers="Field3"> Access Type Name </td>
<td class="" headers="Field4"> Access type description. </td>
</tr>
</table>
</div>
My python code:
from lxml import etree
xml_ = "tem.xml"
xsl_ = "tem.xsl"
xsl_p = etree.parse(xsl_)
transform = etree.XSLT(xsl_p)
xml_p = etree.parse(xml_)
result = transform(xml_p)
# Write the transformed XML to a file
output_file = 'transformed_output.html '
with open(output_file, 'wb') as file:
file.write(etree.tostring(result, pretty_print=True, encoding='UTF-8'))
print(f"Transformed HTML written to {output_file}")
You can try this tem.xsl (XSLT) to get an html:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>Tabelle</title>
<style>
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
th {
background-color: #f2f2f2;
text-align: left;
}
span strong {
display: block;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div>
<xsl:for-each select="query/row">
<table class="table table-condensed table-hover">
<span>
<strong>
<xsl:value-of select="GUEST_NAME"/>
</strong>
</span>
<tr>
<th class="" id="Field3">Access Type</th>
<th class="" id="Field4">Description</th>
</tr>
<tr>
<td class="" headers="Field3">
<xsl:value-of select="ACCESS_TYPE"/>
</td>
<td class="" headers="Field4">
<xsl:value-of select="ACCESS_DESCRIPTION"/>
</td>
</tr>
</table>
</xsl:for-each>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>