I am trying to figure out how and where does an XSL filter need to be added to filter out multiple input. Below is my XML:
<?xml version="1.0" encoding="utf-8"?>
<product_list>
<header>
<brands>
<brand id="A1" name="ABC">ABC Brand</brand>
<brand id="A2" name="DEF">DEF Brand</brand>
</brand>
<groups>
<group id="PN08" name="Air Pneumatic Parts"/>
<group id="EL04" name="Lamps & Electrical Parts"/>
<group id="GE06" name="General Parts"/>
</groups>
</header>
<group id="PN08" name="Air Pneumatic Parts">
<product id="PN080101">
<name>Clutch Servo - SCANIA</name>
<brand>ABC</brand>
</product>
<product id="PN080102">
<name>Clutch Servo - VOLVO</name>
<brand>ABC</brand>
</product>
<product id="PN080103">
<name>Clutch Servo - DAF</name>
<brand>DEF</brand>
</product>
</group>
<group id="EL04" name="Lamps & Electrical Parts">
<product id="EL040101">
<name>Headlamp - MERCEDES</name>
<brand>ABC</brand>
</product>
</group>
</product_list>
and my XSL:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:param name="selected_brand" select="'all'"/>
<xsl:param name="selected_group" select="'all'"/>
<xsl:param name="Page" select="0" />
<xsl:template match="/">
<html>
<body>
<xsl:value-of select='$selected_brand'/> Brand, <xsl:value-of select='$selected_group'/> Group, Page: <xsl:value-of select='$Page'/><br/>
<form method="post" action="t1.asp">
<table>
<tr>
<td>
Brand
<select name="brand" value="{$selected_brand}" onchange="submit()">
<option value="all">
<xsl:if test="$selected_brand='all'">
<xsl:attribute name="selected">Selected</xsl:attribute>
</xsl:if>
All</option>
<xsl:for-each select="product_list/brands/brand">
<option value="{@name}">
<xsl:if test="$selected_brand=@name">
<xsl:attribute name="selected">Selected</xsl:attribute>
</xsl:if>
<xsl:value-of select="@name" /> </option>
</xsl:for-each>
</select>
</td>
<td>
Group
<select name="group" value="{$selected_group}" onchange="submit()">
<option value="all">
<xsl:if test="$selected_group='all'">
<xsl:attribute name="selected">Selected</xsl:attribute>
</xsl:if>
All</option>
<xsl:for-each select="product_list/groups/group">
<option value="{@name}">
<xsl:if test="$selected_group=@name">
<xsl:attribute name="selected">Selected</xsl:attribute>
</xsl:if>
<xsl:value-of select="@name" /> </option>
</xsl:for-each>
</select>
</td>
</tr>
</table>
</form>
<br/>
<xsl:apply-templates select="product_list"/>
</body>
</html>
</xsl:template>
<xsl:template match="product_list">
<table >
<xsl:apply-templates select="group"/>
</table>
</xsl:template>
<xsl:template match="group">
<xsl:apply-templates select="product[($selected_brand='all') or ($selected_brand=./brand)]">
<xsl:sort select="product[@id]"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="product">
<tr>
<td><xsl:value-of select="position()"/></td>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="brand"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
I manage to get the form to work with the brand but I have no idea how to add in another group filter in such way that:
- When Brand = All & Group = All, display all records
- When Brand = ABC & Group = All, display records PN080101, PN080102 & EL040101
- When Brand = All & Group = PN08, display records PN080101, PN080102 & PN080103
- When Brand = ABC & Group = EL04, display record EL040101
Where should I put the filter? It is not sitting at the same children as the product node. How should I filter out basing on the parent node?
[($selected_group='all') or ($selected_group=./group)]
CodePudding user response:
Since you are selecting groups first and then products inside the group, you could put the filtering on line 59:
<xsl:apply-templates select="group"/>
by changing it to something like this:
<xsl:apply-templates select="group[$selected_group='all' or $selected_group=./@id]"/>
Or, alternatively, if you want to keep all your filtering in one place you could put it on line 64:
<xsl:apply-templates select="product[($selected_brand='all') or ($selected_brand=./brand)]">
by changing it to:
<xsl:apply-templates select="product[($selected_brand='all' or $selected_brand=./brand) and
($selected_group='all' or $selected_group=parent::group/@id)]">
Here, the key is using the parent
axis to reach out to the group
element that is the parent of the product
.