Subject: [xsl] find first occurrence of attribute value grouped by element From: John Pallister <jpallister@xxxxxxxxxxxx> Date: Mon, 23 Sep 2002 11:23:13 -0400 |
Hi, This is my first posting to this list site. I have tried to search the archives and other sites to help with my problem, but have not found anything which addresses it specifically. Please excuse my newbieness. Problem: Determine the first occurrence of a particular attribute value grouped by element. Example data: testdata.xml: <?xml version="1.0" ?> <!-- simplified test data example 1--> <root> <testdata Unit_id="000001"> <test id="test1" passed='F' timestamp="2002-09-01 12:00:00"></test> <test id="test2" passed='T' timestamp="2002-09-01 13:00:00"></test> <test id="test1" passed='T' timestamp="2002-09-02 11:00:00"></test> </testdata> <testdata Unit_id="000002"> <test id="test1" passed='T' timestamp="2002-09-01 10:00:00"></test> <test id="test2" passed='T' timestamp="2002-09-01 13:00:00"></test> <test id="test3" passed='T' timestamp="2002-09-02 11:00:00"></test> </testdata> <testdata Unit_id="000003"> <test id="test1" passed='T' timestamp="2002-09-03 10:00:00"></test> <test id="test3" passed='T' timestamp="2002-09-04 14:00:00"></test> <test id="test2" passed='F' timestamp="2002-09-02 11:00:00"></test> </testdata> </root> Desired output: ---------------------------------------------------------------------------- ---------------- Test Total Attempts Total Pass Total Fail Pass on First Attempt First Run Ratio ---------------------------------------------------------------------------- ---------------- test 1 4 3 1 2 66.7% test 2 4 2 2 1 25% test 3 2 2 0 2 100% My XSLT attempt at producing the listed output: testdata.xsl: <?xml version="1.0" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <xsl:key name="keyTest" match="test" use="@id" /> <xsl:key name="keyPassed" match="test[@passed='T']" use="@id" /> <xsl:key name="keyFailed" match="test[@passed='F']" use="@id" /> <!-- The key that follows must be incorrect... :( --> <xsl:key name="keyFRP" match="test[@passed='T' and not(preceding-sibling::*[@passed='F'])]" use="@id" /> <xsl:template match="/"> <html> <head> <title>Summary Report</title> </head> <body> <table border="1"> <tr> <th>Test</th> <th>Total Attempts</th> <th>Total Pass</th> <th>Total Fail</th> <th>Pass on First Attempt</th> <th>First Run Ratio</th> </tr> <testdata> <xsl:call-template name="summary_list" /> </testdata> </table> </body> </html> </xsl:template> <xsl:template match="//testdata//test[generate-id(.) = generate-id(key('keyTest', @id))]" name="summary_list"> <xsl:for-each select = "//testdata//test[generate-id(.) = generate-id(key('keyTest', @id))]" > <!--<xsl:variable name="theTS" select="@id" />--> <xsl:variable name="firstUnit" select="../@Unit_id" /> <tr> <!-- Display the Test Name! --> <td align="center"><b><xsl:value-of select = "@id" /></b></td> <!-- Count all Tests! --> <td align="center"><xsl:value-of select = "count(key('keyTest',@id))" /></td> <!-- Count the Passes! --> <td align="center"><xsl:value-of select = "count(key('keyPassed',@id))" /></td> <!-- Count the Fails! --> <td align="center"><xsl:value-of select = "count(key('keyFailed',@id))" /></td> <!-- Try to Count the first pass! --> <td align="center"><xsl:value-of select = "count(key('keyFRP',@id))" /></td> <!-- Calculate First Run Ratio --> <xsl:choose> <xsl:when test="count(key('keyFRP',@id))"> <td align="right"> <xsl:value-of select = "format-number(count(key('keyFRP',@id)) div count(key('keyTest',@id)),'###.###%')" /> </td> </xsl:when> <xsl:otherwise> <td align="right"><xsl:value-of select = "'0%'" /></td> </xsl:otherwise> </xsl:choose> </tr> </xsl:for-each> </xsl:template> </xsl:stylesheet> This XSLT file seemed to work for the first data example, but the second example listed below failed to generate the proper results. <?xml version="1.0" ?> <!-- simplified test data example 2 --> <root> <testdata Unit_id="000001"> <test id="test1" passed='F' timestamp="2002-09-01 12:00:00"></test> <test id="test2" passed='F' timestamp="2002-09-01 13:00:00"></test> <test id="test1" passed='T' timestamp="2002-09-02 11:00:00"></test> <test id="test2" passed='T' timestamp="2002-09-02 14:00:00"></test> </testdata> <testdata Unit_id="000002"> <test id="test1" passed='T' timestamp="2002-09-01 10:00:00"></test> <test id="test2" passed='T' timestamp="2002-09-01 13:00:00"></test> <test id="test3" passed='T' timestamp="2002-09-02 11:00:00"></test> </testdata> <testdata Unit_id="000003"> <test id="test1" passed='T' timestamp="2002-09-03 10:00:00"></test> <test id="test3" passed='T' timestamp="2002-09-04 14:00:00"></test> <test id="test2" passed='F' timestamp="2002-09-02 11:00:00"></test> <test id="test4" passed='T' timestamp="2002-09-07 11:00:00"></test> </testdata> </root> It did seem to work for the first data set, but it failed to work correctly for the second data set! I was thinking that if I counted the passes for a test for a given unit_id where a fail had not occurred, that this would give the desired result. I know that the key that I have created for the first pass occurrence is not correct. The 'test4' is not counted as a first run pass for some reason. I am not sure what the proper key should be. I had not used the timestamp data because I am assuming that a fail will not occur after a pass of a particular test, and that a test would not be taken after a pass had occurred. What would the proper approach be to solve this problem? Any help will be greatly appreciated! Thanks, John Pallister jpallister@xxxxxxxxxxxx XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] xsl for parsing strange x, Aparna Konduri | Thread | RE: [xsl] find first occurrence of , James Fuller |
[xsl] xsl for parsing strange xml, Aparna Konduri | Date | RE: [xsl] Urgent Help Needed in XSL, Marrow |
Month |