Reputation: 1
I am very new to XSLT. Unable to figure out , how to show a particular row only if the child nodes contain one of the specific texts.
In my case we have a list of call logs. The phone number can be of multiple type, but i want show them in table only when the phone number type is either voice or sms.
My XML
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="example.xsl"?>
<CallLogs>
<cInfoBj>
<phNoBJ>
<phNo>123</phNo>
<phTypeBj>
<phTypeName>VOICE</phTypeName>
</phTypeBj>
</phNoBJ>
</cInfoBj>
<cInfoBj>
<phNoBJ>
<phNo>456</phNo>
<phTypeBj>
<phTypeName>VOICE</phTypeName>
</phTypeBj>
<phTypeBj>
<phTypeName>SMS</phTypeName>
</phTypeBj>
</phNoBJ>
</cInfoBj>
<cInfoBj>
<phNoBJ>
<phNo>789</phNo>
<phTypeBj>
<phTypeName>SMS</phTypeName>
</phTypeBj>
</phNoBJ>
</cInfoBj>
<cInfoBj>
<phNoBJ>
<phNo>890</phNo>
<phTypeBj>
<phTypeName>FAX</phTypeName>
</phTypeBj>
</phNoBJ>
</cInfoBj>
</CallLogs>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr bgcolor="#9acd32">
<th>Phone Number</th>
<th>Type</th>
</tr>
<xsl:for-each select="/CallLogs/cInfoBj/phNoBJ">
<tr>
<td><xsl:value-of select="phNo"/></td>
<td>
<xsl:for-each select="phTypeBj">
<div><xsl:value-of select="phTypeName"/></div>
</xsl:for-each>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 439
Reputation: 163322
Change the xsl:for-each
to xsl:apply-templates
, and define template rules for the different things it can select:
<xsl:apply-templates select="/CallLogs/cInfoBj/phNoBJ"/>
then
<xsl:template match="phNoBJ[.//phTypeName=('VOICE', 'SMS')]">
<tr>
<td><xsl:value-of select="phNo"/></td>
<td>
<xsl:for-each select="phTypeBj">
<div><xsl:value-of select="phTypeName"/></div>
</xsl:for-each>
</td>
</tr>
</xsl:template>
<xsl:template match="phNoBJ"/> <!-drop element if it doesn't match the conditions-->
Template rules are the idiomatic way of structuring XSLT code; if you're a beginner, then every time you find yourself writing xsl:for-each
, consider using xsl:apply-templates
instead.
Upvotes: 1
Reputation: 116993
Change:
<xsl:for-each select="/CallLogs/cInfoBj/phNoBJ">
to:
<xsl:for-each select="/CallLogs/cInfoBj/phNoBJ[phTypeBj/phTypeName='VOICE' or phTypeBj/phTypeName='SMS']">
You may need to add a similar predicate to your other xsl:for-each
instruction if you don't want to list the additional types for numbers with multiple types.
Upvotes: 0