xsl-list
[Top] [All Lists]

Re: [xsl] Comparing attribute values of nodes in different contexts

2010-02-06 03:23:10
This is a typical application for "Grouping", which is explained, with examples,
in http://www.w3.org/TR/xslt20/#grouping.

Except for the HTML tags, this should do it:

  <xsl:template match="/caller">
    <xsl:for-each-group select="contact" group-by="@callID">
      Call connected on <xsl:value-of select="@timeCallInitiated"/>.
      There are <xsl:value-of select="count(current-group())"/>
related connections as follows:
      <xsl:for-each select="current-group()">
        Connection: <xsl:value-of select="@timeAgentConnected"/> to
agent <xsl:value-of select="@agent"/>
      </xsl:for-each>
    </xsl:for-each-group>
  </xsl:template>

-W
PS: Seems like you got an answer, so you do know how to ask ;-)

On Fri, Feb 5, 2010 at 11:46 PM, Robert Bourdeau 
<rhbourdeau(_at_)gmail(_dot_)com> wrote:

Consider the following XML document, showing a set of telephone calls
received from a specific telephone number, along with the various
internal connections to different employees from the time the call is
first connected to the phone system until the call is terminated.


<caller callerID="9195551212">
   <contact
       callID="1"
       contactID="3"
       timeCallInitiated="2010-02-04T09:42:58"
       timeAgentConnected="2010-02-04T09:43:23"
       agent="Jamie Smith"
   />
   <contact
       callID="1"
       contactID="2"
       timeCallInitiated="2010-02-04T09:42:58"
       timeAgentConnected="2010-02-04T09:43:23"
       agent="Angela Jones"
   />
   <contact
       callID="1"
       contactID="1"
       timeCallInitiated="2010-02-04T09:42:58"
       timeAgentConnected="2010-02-04T09:42:58"
       agent="Desi Johnson"
   />
   <contact
       callID="2"
       contactID="3"
       timeCallInitiated="2010-02-04T09:41:45"
       timeAgentConnected="2010-02-04T09:42:10"
       agent="Jamie Smith"
   />
   <contact
       callID="2"
       contactID="2"
       timeCallInitiated="2010-02-04T09:41:45"
       timeAgentConnected="2010-02-04T09:42:10"
       agent="Angela Jones"
   />
   <contact
       callID="2"
       contactID="1"
       timeCallInitiated="2010-02-04T09:41:45"
       timeAgentConnected="2010-02-04T09:41:45"
       agent="Julia Billings"
   />
   <contact
       callID="3"
       contactID="2"
       timeCallInitiated="2010-01-26T13:29:21"
       timeAgentConnected="2010-01-26T13:29:49"
       agent="Angela Jones"
   />
   <contact
       callID="3"
       contactID="1"
       timeCallInitiated="2010-01-26T13:29:21"
       timeAgentConnected="2010-01-26T13:29:21"
       agent="Desi Johnson"
   />
</caller>

Ideally this XML file would be one level deeper where all "contacts"
having the same value for the callID attribute are grouped together
under a single node. I cannot change that however. And therein lies my
problem. To dumb this down I'd like output as follows:

       Call Connected on 2010-02-04
       There are 3 related connections as follows:
       Connection: 2010-02-04T09:43:23 to agent Jamie Smith
       Connection: 2010-02-04T09:43:23 to agent Angela Jones
       Connection: 2010-02-04T09:42:58 to agent Desi Johnson
       Call Connected on 2010-02-04
       There are 3 related connections as follows:
       Connection: 2010-02-04T09:42:10 to agent Jamie Smith
       Connection: 2010-02-04T09:42:10 to agent Angela Jones
       Connection: 2010-02-04T09:41:45 to agent Julia Billings
       Call Connected on 2010-01-26
       There are 2 related connections as follows:
       Connection: 2010-01-26T13:29:49 to agent Angela Jones
       Connection: 2010-01-26T13:29:21 to agent Desi Johnson

The Key problem is just one little piece of this:
       'There are 3 related connections as follows:'
How do I get the '3' computed?

For my application, it is important that I output that number BEFORE I
output each of the connections.
Here's the code to produce that output above (with one incomplete part):

       <xsl:template match="/caller">
         <xsl:for-each select="contact">
           <xsl:if test="not(@callID = 
preceding-sibling::contact[1]/@callID)">
               <br/>
               Call connected on <xsl:value-of
select="scripts:justDate(@timeCallInitiated)"/>
               <br/>
               There are
               <xsl:value-of select="count(/caller/contact[(_at_)callID = 
?])"/>
               related connections as follows:
           </xsl:if>

           <br/>
           Connection:
               <xsl:value-of select="@timeAgentConnected"/>
           to agent
               <xsl:value-of select="@agent"/>
         </xsl:for-each>
       </xsl:template>

See that question mark '?' up there? What goes there? The @callID
refers to the context of the preceding XPath expression. I want to
only count those 'contact' nodes that have the same attribute value of
'callID' as the node being currently processed by the for-each node.
But I have no idea how to reference the context of the for-each node
from within that count function.

I clearly need a better theoretical understanding of how different
contexts are used in the XSL processing. But there seems to be a large
gap between the technical documentation at w3c and how to even ASK
about problems like this!

Any help here?

A totally alternative approach to the XSL stylesheet is perfectly acceptable.

Best

Robert H. Bourdeau

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>