By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,208 Members | 1,550 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,208 IT Pros & Developers. It's quick & easy.

Eliminating duplicate information in selected sorted rows

P: n/a
Can somebody help me with this please...

I have an xml file along the lines of

<results>
<result status="Pass">
<person name="Fred"/>
<subject name="English" />
</result>
<result status="Pass">
<person name="Harry"/>
<subject name="Maths" />
</result>
<result status="Fail">
<person name="Fred"/>
<subject name="History" />
</result>
<result status="Fail">
<person name="Harry"/>
<subject name="English" />
</result>
<result status="Pass">
<person name="Fred"/>
<subject name="Maths" />
</result>
<result status="Pass">
<person name="Harry"/>
<subject name="History" />
</result>
</results>

And need to generate html for all result staus="Passes" sorted and displayed
like this:

Passes:
Name Subject
------ --------
Fred English
- Maths
Harry History
- Maths

My best attempt so far is:

....
<xsl:for-each select="results/result[@status='Pass']">
<xsl:sort select="person/@name"/>
<tr>
<td>
<xsl:value-of select="person/@name"/>
<xsl:value-of select="subject/@name"/>
</td>
</tr>
</xsl:for-each>
....

Which gives:

Passes:
Name Subject
------ --------
Fred English
Fred Maths
Harry History
Harry Maths

The problems as I see it are that the output is a sub-set af the whole data,
and it is sorted.

Any ideas on how to remove the duplicate entries in the first column would
be very welcome.

--
Matt

Oct 7 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Ixa
> <xsl:for-each select="results/result[@status='Pass']">
<xsl:sort select="person/@name"/>
<tr>
<td>
<xsl:value-of select="person/@name"/>
<xsl:value-of select="subject/@name"/>
</td>
</tr>
</xsl:for-each> [...] Any ideas on how to remove the duplicate entries in the first column
would be very welcome.


One suggestion:

---8<---8<---
<xsl:variable name="name" select="person/@name"/>
<xsl:if test="not(preceding::person[@name = $name])">
<xsl:value-of select="person/@name"/>
</xsl:if>
---8<---8<---

--
Ixa

Oct 8 '05 #2

P: n/a
"Ixa" <ix*@niksula.hut.fi> wrote in message
news:43***********************@news.fv.fi...
<xsl:for-each select="results/result[@status='Pass']">
<xsl:sort select="person/@name"/>
<tr>
<td>
<xsl:value-of select="person/@name"/>
<xsl:value-of select="subject/@name"/>
</td>
</tr>
</xsl:for-each>

[...]
Any ideas on how to remove the duplicate entries in the first column
would be very welcome.


One suggestion:

---8<---8<---
<xsl:variable name="name" select="person/@name"/>
<xsl:if test="not(preceding::person[@name = $name])">
<xsl:value-of select="person/@name"/>
</xsl:if>
---8<---8<---


Thanks for the suggestion. I tried it but got blanks for *every* line.

--
Matt
Oct 8 '05 #3

P: n/a
Ixa
> Thanks for the suggestion. I tried it but got blanks for *every* line.

Hmm, I get the expected result. Here's the script that I used:

---8<---8<---
<xsl:for-each select="results/result[@status='Pass']">
<xsl:sort select="person/@name"/>
<tr>
<td>
<xsl:variable name="name" select="person/@name"/>
<xsl:if test="not(preceding::person[@name = $name])">
<xsl:value-of select="person/@name"/>
</xsl:if>
</td>
<td>
<xsl:value-of select="subject/@name"/>
</td>
</tr>
</xsl:for-each>
---8<---8<---

and the result (name once in first column and all passed items in
second column):

---8<---8<---
<tr>
<td>Fred</td>
<td>English</td>
</tr>
<tr>
<td></td>
<td>Maths</td>
</tr>
<tr>
<td>Harry</td>
<td>Maths</td>
</tr>
<tr>
<td></td>
<td>History</td>
</tr>
---8<---8<---

--
Ixa

Oct 8 '05 #4

P: n/a
"Ixa" <ix*@niksula.hut.fi> wrote in message
news:43***********************@news.fv.fi...
Thanks for the suggestion. I tried it but got blanks for *every* line.


Hmm, I get the expected result. Here's the script that I used:

....
I tried again, and got these results - the script is after (sorry for the
length)...
With all the data in place:
Dick Geography
Dick History
Harry English
Harry French
Harry Maths
Tom English
Tom Maths
Processing person names:
Geography
History
English
French
Harry Maths
English
Tom Maths
xml:

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="report.xsl"?>
<report>
<results>
<result status="Pass">
<subject name="Maths"/>
<person name="Tom" />
</result>
<result status="Fail">
<subject name="Maths"/>
<person name="Dick" />
</result>
<result status="Pass">
<subject name="Maths"/>
<person name="Harry" />
</result>
<result status="Fail">
<subject name="History"/>
<person name="Tom" />
</result>
<result status="Pass">
<subject name="History"/>
<person name="Dick" />
</result>
<result status="Fail">
<subject name="History"/>
<person name="Harry" />
</result>
<result status="Pass">
<subject name="English"/>
<person name="Tom" />
</result>
<result status="Fail">
<subject name="English"/>
<person name="Dick" />
</result>
<result status="Pass">
<subject name="English"/>
<person name="Harry" />
</result>
<result status="Fail">
<subject name="Geography"/>
<person name="Tom" />
</result>
<result status="Pass">
<subject name="Geography"/>
<person name="Dick" />
</result>
<result status="Fail">
<subject name="Geography"/>
<person name="Harry" />
</result>
<result status="Pass">
<subject name="French"/>
<person name="Harry" />
</result>
</results>
</report>

xsl:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/report">
<html>
<body>
<table border="1">
<xsl:for-each select="results/result[@status='Pass']">
<xsl:sort select="person/@name"/>
<xsl:sort select="subject/@name"/>
<tr>
<td>
<xsl:value-of select="person/@name"/>
</td>
<td>
<xsl:value-of select="subject/@name"/>
</td>
</tr>
</xsl:for-each>
</table>
<table border="1">
<xsl:for-each select="results/result[@status='Pass']">
<xsl:sort select="person/@name"/>
<xsl:sort select="subject/@name"/>
<tr>
<td>
<xsl:variable name="name" select="person/@name"/>
<xsl:if test="not(preceding::person[@name = $name])">
<xsl:value-of select="person/@name"/>
</xsl:if> 
</td>
<td>
<xsl:value-of select="subject/@name"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

--
Matt
Oct 8 '05 #5

P: n/a
Ixa
> I tried again, and got these results - the script is after

So the sorting confuses the tests and another approach might be better.
Here's one (search for unique persons and their successful results, not
vice versa):

---8<---8<---
<table border="1">
<xsl:for-each select="//person/@name">
<xsl:sort/>
<xsl:variable name="name" select="."/>
<xsl:variable name="items"
select="/report/results/result[person[@name = $name] and
@status='Pass']"/>
<xsl:if test="not(preceding::person[@name = $name])">
<tr>
<td>
<xsl:value-of select="."/>
</td>
<td>
<xsl:for-each select="$items">
<xsl:sort select="subject/@name"/>
<xsl:if test="position() = 1">
<xsl:value-of select="subject/@name"/>
</xsl:if>
</xsl:for-each>
</td>
</tr>
<xsl:for-each select="$items">
<xsl:sort select="subject/@name"/>
<xsl:if test="position() &gt; 1">
<tr>
<td/>
<td>
<xsl:value-of select="subject/@name"/>
</td>
</tr>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</table>
---8<---8<---

--
Ixa

Oct 8 '05 #6

P: n/a
"Ixa" <ix*@niksula.hut.fi> wrote in message
news:43***********************@news.fv.fi...
I tried again, and got these results - the script is after


So the sorting confuses the tests and another approach might be better.
Here's one (search for unique persons and their successful results, not
vice versa):


Lateral thinking - I love it! It works great!

Thanks for your trouble :-)

--
Matt
Oct 8 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.