Here's what I'm trying to do: I have a list of Faculties, within each of which is a list of departments. I want to display the entire list of departments, sorted by Department name, but indicating the faculty.
The XML looks like this:
<Faculties>
<Faculty Name="Science">
<Department name="dept2">
<head>Mr X</head>
<building>A Block</building>
etc...
</Department>
<Department name="dept3">
<head>Mr X</head>
<building>B Block</building>
etc...
</Department>
</Faculty>
<Faculty Name="Education">
<Department name="dept1">
<head>Mr Y</head>
<building>C Block</building>
etc...
</Department>
</Faculty>
</Faculties>
The XSLT looks something like this: (I've simplified the XSLT for explanation purposes.)
<xsl:for-each select="Faculties">
<xsl:sort select="DepartmentName">
<xsl:for-each select="Departments">
<xsl:element name="div">
<xsl:attribute name="id"><xsl:value-of select="facultName"></xsl:attribute>
<h3><xsl:value-of select="deptName"> - <xsl:value-of select="facultName"></h3>
//More stuff here
</xsl:element>
</xsl:for-each>
</xsl:for-each>
I'd like the output to look like:
Dept1 (Education)
Head: Mr Y
Building: C Block
Dept2 (Science)
Head: Mr X
Building: A Block
Dept3 (Science)
Head: Mr X
Building: B Block
Where it's sorted by Department Name.
I also want to be able to hide all the departments from a particular faculty using Javascript, i.e. hide all divs which have a particular faculty in the id.
I'm not even sure if what I'm attempting is possible (or logical). My only other option seems to be generating a completely new list of departments, with faculty as one of the elements. Then I'll only need one for-each. Unfortunately, I can't really control how the XML is generated, so I'm hoping to be able to do it this way.
I appreciate any help. Thanks!
If you want to list all departments in name order, regardless of the faculty, you can simply iterate over the departments directly
<xsl:for-each select="Faculty/Department">
<xsl:sort select="@deptName" />
</xsl:for-each>
Then, to get the faculty name for the department, you can access the parent element quite easily
<xsl:value-of select="../@facultyName" />
So, assuming you have the following XML
<Faculties>
<Faculty id="1" facultyName="Beer Drinking">
<Department id="1" deptName="Real Ale" />
<Department id="2" deptName="Lager" />
</Faculty>
<Faculty id="2" facultyName="Food">
<Department id="3" deptName="Fish and Chips" />
<Department id="4" deptName="Pies" />
</Faculty>
</Faculties>
When you apply the following XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/Faculties">
<xsl:apply-templates select="Faculty/Department">
<xsl:sort select="@deptName" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Department">
<div id="{../@facultyName}">
<h3><xsl:value-of select="concat(@deptName, ' - ', ../@facultyName)" /></h3>
</div>
</xsl:template>
</xsl:stylesheet>
The following is output
<div id="Food">
<h3>Fish and Chips - Food</h3>
</div>
<div id="Beer Drinking">
<h3>Lager - Beer Drinking</h3>
</div>
<div id="Food">
<h3>Pies - Food</h3>
</div>
<div id="Beer Drinking">
<h3>Real Ale - Beer Drinking</h3>
</div>
Do note, it is usually preferably to use xsl:apply-templates over xsl:for-each, and so this is what I have used in the XSLT.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With