[xsl] distinct moves problem

Subject: [xsl] distinct moves problem
From: "Ahmad J. Reeves" <ahmad@xxxxxxxxxxxxxx>
Date: Wed, 09 Jan 2002 10:09:40 +0000
Hi Dimitre and all,

I've just noticed that the list generated doesnt allow
for the fact that an individual may return to the same room
after he has left it. Rather it lists, I think, all of the
unique rooms he has passed through. I know from studying an individuals
log that they returned to a room they were originally in, but the
stylesheet contains no repetitions. So for example with the following xml

<LOG> 
<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>10010</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45040</LOCATION_ID> 
<TARGET_CHARACTER_ID>444444</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>10010</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45030</LOCATION_ID> 
<TARGET_CHARACTER_ID>444444</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>10010</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45020</LOCATION_ID> 
<TARGET_CHARACTER_ID>444444</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>444444</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45010</LOCATION_ID> 
<TARGET_CHARACTER_ID>10010</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>444444</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45030</LOCATION_ID> 
<TARGET_CHARACTER_ID>10010</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>444444</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45030</LOCATION_ID> 
<TARGET_CHARACTER_ID>10010</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>10010</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45040</LOCATION_ID> 
<TARGET_CHARACTER_ID>60060</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 
</LOG> 

The output for character id 10010 should be: 

45040
45030
45020
45040 (again)= 3 moves = correct

but actually produces

Room moves by character:
Character_ID: 10010:
    45040
    45030
    45020 = 2 moves = false

So this misses another move the charater made back to the original room.
I need an accurate count af the exact number of moves they make through
different and the same rooms rather than the number of distinct rooms they
passed through. Can this still be done with the same list and key?

Cheers

Ahmad








Ahmad J Reeves <ahmad at dcs dot qmul dot ac dot uk> wrote: 

> Just wanted to say thanks once again for helping 
> questions. This is the best list I've seen for 
> genral helpfulness and good things! 
> 
> Just a quick question, with the same data.. 
> 
> <LOG> 
> <DIRECT> 
> <COMMUNICATION_TYPE> PAGETELL </COMMUNICATION_TYPE> 
> <Invoc_serial> 27 </Invoc_serial> 
> <Serial> 3087908 </Serial> 
> <USAGE> TELL </USAGE> 
> <MESSAGE_TYPE> EMOTE </MESSAGE_TYPE> 
> <CHARACTER_ID> 10010 </CHARACTER_ID> 
> <CHARACTER_STATUS> 3 </CHARACTER_STATUS> 
> <LOCATION_ID> 45040 </LOCATION_ID> 
> <TARGET_CHARACTER_ID> 444444 </TARGET_CHARACTER_ID> 
> <TARGET_CHARACTER_STATUS> 6 </TARGET_CHARACTER_STATUS> 
> <TARGET_CHARACTER_LOCATION_ID> 23222 
> </TARGET_CHARACTER_LOCATION_ID> 
> <MESSAGE>hello</MESSAGE> 
> <TIME> 'Mon, 26 Nov 2001 15:40:29 +0000' </TIME> 
> </DIRECT> 
> 
> etc etc 50,000 or so times 
> </LOG> 
> 
> I also need to track the movement of a character. So 
> for example I know that a certain character_id has 
> been in say 25 rooms of which 9 were unique, but 
> I cant see how I can work out the number of distinct moves he makes 
> using xsl. 
> 
> So I can get output like this:- 
> 
> Ch-ID in-room Message Target-ID time 
> 23470 45040 Hello 12345 10:19 
> 23470 43333 Hi 23432 10:23 
> 23470 45040 Yo 43333 10:44 
> 
> etc.. 
> etc.. 
> 
> This tells me he was in a total of three rooms of which 
> 2 were unique AND he has made 2 MOVES so far. So I need 
> to work out the total number of distinct moves per character-ID, 
> with a total and average for all of them. 

Hi Ahmad, 

This problem is built upon the previous one for which you already have the
solution: 

http://sources.redhat.com/ml/xsl-list/2001-12/msg01127.html 

To calculate the number of distinct rooms a "character" has been in, you
can add to 
the solution the following: 

<xsl:key name="kLocByCharacter" 
match="LOCATION_ID" 
use="../CHARACTER_ID"/> 

<xsl:key name="kLocByValandChar" 
match="LOCATION_ID" 
use="concat(., '|', ../CHARACTER_ID)"/> 

The first key gives all "LOCATION_ID"s (rooms) for a "character". 

The second key gives all "LOCATION_ID"s (rooms) that have a given
combination of 
values for a "LOCATION_ID" (room) and the "character" that was there. 

In order to get a list of distinct characters and for each of them a list of 
distinct rooms, add this code at the end of the template: 

<xsl:for-each select="$vUniqueCharactersSending> 
<xsl:value-of select="concat('Character_ID: ', 
CHARACTER_ID, 
':', 
$NL 
)"/> 
<xsl:for-each select="key('kLocByCharacter',CHARACTER_ID) 
[generate-id() 
= 
generate-id(key('kLocByValandChar', 
concat(., 
'|', 
current()/CHARACTER_ID 
) 
)[1] 
) 
]> 


<xsl:value-of select="concat(' ', ., $NL)"/> 

</xsl:for-each> 

</xsl:for-each> 


The complete stylesheet will now be: 

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";> 

<xsl:output method="text"/> 

<xsl:key name="kByID" match="DIRECT" use="CHARACTER_ID"/> 
<xsl:key name="kByTargetID" match="TARGET_CHARACTER_ID" use="."/> 
<xsl:key name="kLocByCharacter" 
match="LOCATION_ID" 
use="../CHARACTER_ID"/> 

<xsl:key name="kLocByValandChar" 
match="LOCATION_ID" 
use="concat(., '|', ../CHARACTER_ID)"/> 

<xsl:variable name="vUniqueCharactersSending" 
select="LOG/DIRECT[generate-id() 
= 
generate-id(key('kByID', 
CHARACTER_ID 
)[1] 
) 
]"/> 

<xsl:variable name="vUniqueCharactersReceiving" 
select="LOG/DIRECT/TARGET_CHARACTER_ID 
[generate-id() 
= 
generate-id(key('kByTargetID', 
. 
)[1] 
) 
]"/> 

<xsl:variable name="vNumCharactersSending" 
select="count($vUniqueCharactersSending)"/> 

<xsl:variable name="vNumCharactersReceiving" 
select="count($vUniqueCharactersReceiving)"/> 

<xsl:variable name="vTotalSent" 
select="count(LOG/DIRECT/CHARACTER_ID)"/> 

<xsl:variable name="NL" select="'&#xA;'"/> 

<xsl:template match="/> 
<xsl:for-each select="$vUniqueCharactersSending> 
<xsl:value-of select="concat('CHARACTER_ID ',CHARACTER_ID, 
' sent ', 
count(key('kByID',CHARACTER_ID)), 
' messages, received ', 
count(key('kByTargetID',CHARACTER_ID)), 
$NL 
)"/> 
</xsl:for-each> 

<xsl:for-each select="$vUniqueCharactersReceiving 
[not(key('kByID', .))]> 

<xsl:value-of select="concat('CHARACTER_ID ', ., 
' sent 0 messages, received ', 
count(key('kByTargetID',.)), 
$NL 
)"/> 
</xsl:for-each> 

<xsl:value-of select="$NL"/> 
<xsl:value-of select="concat('Number of characters having sent a message: ', 
$vNumCharactersSending, 
$NL 
)"/> 

<xsl:value-of select="concat('Number of characters having received a
message: ', 
$vNumCharactersReceiving, 
$NL 
)"/> 

<xsl:value-of select="$NL"/> 
<xsl:value-of select="concat('Total sent: ', 
$vTotalSent, 
', Average sent by a sending character: ', 
$vTotalSent div $vNumCharactersSending, 
'&#xA;', 

'Total received: ', 
$vTotalSent, 
', Average received by a receiving character: ', 
$vTotalSent div $vNumCharactersReceiving, 
'&#xA;' 

)"/> 

<xsl:value-of select="$NL"/> 
<xsl:value-of select="concat('Room moves by character:', $NL)"/> 

<xsl:for-each select="$vUniqueCharactersSending> 
<xsl:value-of select="concat('Character_ID: ', 
CHARACTER_ID, 
':', 
$NL 
)"/> 
<xsl:for-each select="key('kLocByCharacter',CHARACTER_ID) 
[generate-id() 
= 
generate-id(key('kLocByValandChar', 
concat(., 
'|', 
current()/CHARACTER_ID 
) 
)[1] 
) 
]> 


<xsl:value-of select="concat(' ', ., $NL)"/> 

</xsl:for-each> 

</xsl:for-each> 

</xsl:template> 
</xsl:stylesheet> 


When this transformation is applied upon the following source xml document: 

<LOG> 
<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>10010</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45040</LOCATION_ID> 
<TARGET_CHARACTER_ID>444444</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>10010</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45040</LOCATION_ID> 
<TARGET_CHARACTER_ID>444444</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>10010</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45020</LOCATION_ID> 
<TARGET_CHARACTER_ID>444444</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>444444</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45010</LOCATION_ID> 
<TARGET_CHARACTER_ID>10010</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>444444</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45030</LOCATION_ID> 
<TARGET_CHARACTER_ID>10010</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>444444</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45030</LOCATION_ID> 
<TARGET_CHARACTER_ID>10010</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 

<DIRECT> 
<COMMUNICATION_TYPE>PAGETELL</COMMUNICATION_TYPE> 
<Invoc_serial>27</Invoc_serial> 
<Serial>3087908</Serial> 
<USAGE>TELL</USAGE> 
<MESSAGE_TYPE>EMOTE</MESSAGE_TYPE> 
<CHARACTER_ID>50050</CHARACTER_ID> 
<CHARACTER_STATUS>3</CHARACTER_STATUS> 
<LOCATION_ID>45000</LOCATION_ID> 
<TARGET_CHARACTER_ID>60060</TARGET_CHARACTER_ID> 
<TARGET_CHARACTER_STATUS>6</TARGET_CHARACTER_STATUS> 
<TARGET_CHARACTER_LOCATION_ID>23222</TARGET_CHARACTER_LOCATION_ID> 
<MESSAGE>hello</MESSAGE> 
<TIME>'Mon, 26 Nov 2001 15:40:29 +0000'</TIME> 
</DIRECT> 
</LOG> 



the result is: 

CHARACTER_ID 10010 sent 3 messages, received 3 
CHARACTER_ID 444444 sent 3 messages, received 3 
CHARACTER_ID 50050 sent 1 messages, received 0 
CHARACTER_ID 60060 sent 0 messages, received 1 

Number of characters having sent a message: 3 
Number of characters having received a message: 3 

Total sent: 7, Average sent by a sending character: 2.3333333333333335 
Total received: 7, Average received by a receiving character:
2.3333333333333335 

Room moves by character: 
Character_ID: 10010: 
45040 
45020 
Character_ID: 444444: 
45010 
45030 
Character_ID: 50050: 
45000 


Hope that this really helped. 

Cheers, 
Dimitre Novatchev. 

-------------------------------------------------
Ahmad J Reeves BSc (Hons) MSc (Dist) PhD Student
Information, Media & Communication Research Group
Department of Computer Science
Queen Mary, University of London
E1 4NS
Tel +44(0) 207 882 5257
Fax +44(0) 208 980 6533
http://www.dcs.qmw.ac.uk/imc

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread