Jump to content

Grouping and counting problem


JJK

Recommended Posts

I have an XML similar structure like this

<People>	<Person>		<type>Male</type>		<vegetarian>False</vegetarian>	</Person>	<Person>		<type>Female</type>		<vegetarian>False</vegetarian>	</Person>	<Person>		<type>Female</type>		<vegetarian>True</vegetarian>	</Person>	<Person>		<type>Male</type>		<vegetarian>True</vegetarian>	</Person>	<Person>		<type>Male</type>		<vegetarian>False</vegetarian>	</Person>		<Person>		<type>Child</type>		<vegetarian>False</vegetarian>	</Person><People>

Now I want to group all types and count the variants. How many are vegetarian and how many are not. Then total amount of each types.I have manage to do the total counting and sorting between types but I don't know how to count types vegetarians and non-vegetarians for each type?Notice that in my XML there are more types which are unknown. So I cannot use hard coding for types.Output is something like this

<TABLE><TR>	<TD>Gender</TD>	<TD>Vetarian</TD>	<TD>Non-Vegetarian</TD>	<TD>Total</TD></TR><TR>	<TD>Male</TD>	<TD>1</TD>	<TD>2</TD>	<TD>3</TD></TR><TR>	<TD>Female</TD>	<TD>1</TD>	<TD>1</TD>	<TD>2</TD></TR><TR>	<TD>Child</TD>	<TD>0</TD>	<TD>1</TD>	<TD>1</TD></TR></TABLE>

Link to comment
Share on other sites

And how exactly did you arranged the output in that table? I feel this might requre xsl:key which I'm not so experienced with, so showing how you did it might give me a good start.

Link to comment
Share on other sites

you can create this table with this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ><xsl:output method="html"/><xsl:template match="/">	<TABLE>	<TR>		<TD>Gender</TD>		<TD>vegetarian</TD>		<TD>Non-Vegetarian</TD>		<TD>Total</TD>	</TR>	<TR>		<TD>Male</TD>		<TD><xsl:value-of select="count(//Person[type='Male'][vegetarian='True'])" /></TD>		<TD><xsl:value-of select="count(//Person[type='Male'][vegetarian='False'])" /></TD>		<TD><xsl:value-of select="count(//Person[type='Male'])" /></TD>	</TR>	<TR>		<TD>Female</TD>		<TD><xsl:value-of select="count(//Person[type='Female'][vegetarian='True'])" /></TD>		<TD><xsl:value-of select="count(//Person[type='Female'][vegetarian='False'])" /></TD>		<TD><xsl:value-of select="count(//Person[type='Female'])" /></TD>	</TR>	<TR>		<TD>Child</TD>		<TD><xsl:value-of select="count(//Person[type='Child'][vegetarian='True'])" /></TD>		<TD><xsl:value-of select="count(//Person[type='Child'][vegetarian='False'])" /></TD>		<TD><xsl:value-of select="count(//Person[type='Child'])" /></TD>	</TR>	</TABLE></xsl:template></xsl:stylesheet>

If your requirements are more elaborate, than you will need to be more specific

Link to comment
Share on other sites

Just of curiosity. Scince when does "Child" count as a "gender" (hah.. I didn't noticed earlier)?Well, you said yourself that theese aren't the only types, right? Now that aalbetski gave me a good start, I think I could offer you THE solution:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ><xsl:output method="html"/><xsl:template match="/">	<TABLE>	<TR>		<TD>Gender</TD>		<TD>vegetarian</TD>		<TD>Non-Vegetarian</TD>		<TD>Total</TD>	</TR>	<xsl:for-each slect="//type">		<TR>			<TD><xsl:value-of select="."/></TD>			<TD><xsl:value-of select="count(../Person[type=. and vegetarian='True'])" /></TD>			<TD><xsl:value-of select="count(../Person[type=. and vegetarian='False'])" /></TD>			<TD><xsl:value-of select="count(../Person[type=.])" /></TD>		</TR>	</xsl:for-each>	</TABLE></xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

In case you are interested, the following uses the 'Muenchian' method of selecting unique values. It does utilize keys and may be of interest just as another way to do the same thing

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0"><xsl:output method="html"/><xsl:key name="Gender"  match="Person" use="type"/><xsl:template match="/"><table border="1">	<tr>		<td>Gender</td>		<td>Vegetarian</td>		<td>Non-Vegetarian</td>		<td>Total</td>	</tr>	<xsl:for-each select="//Person[count(. | key('Gender', type)[1]) = 1]/type">		<xsl:variable name="gender" select="."/>		<tr>			<td><xsl:value-of select="$gender"/></td>			<td><xsl:value-of select="count(//Person[type=$gender][vegetarian='True'])"/></td>			<td><xsl:value-of select="count(//Person[type=$gender][vegetarian='False'])"/></td>			<td><xsl:value-of select="count(//Person[type=$gender])"/></td>		</tr>	</xsl:for-each></table></xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

Thank you for your answers! I managed to solve my problem with the last aalbetski's sollution. Since I'm still relative new to xml/xsl (etc.) issues I had more complex sollution before these ones. Again it seems that the simpliest ones are the best ones as well. I have still something here to digest but any way I can now do what I wanted. Thanks again.And you were right boen_robot. Child is not a gender but I tried to create something similar to my code and I guess this was the bad addition to my example:) I just tried to add more variants to my example to emphasize the importance of the issue that the type is unknown and can vary.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...