XSL Sorting/Grouping question

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • mandanarchi
    New Member
    • Sep 2008
    • 90

    XSL Sorting/Grouping question

    I found the answer last time I was 'playing' with xsl, but I didn't need to use it then and like an idiot, I didn't save where I found it.
    I've tried Google but it's not coming up with what I need.

    From Access I'm exporting a file to xml in the following format:
    Code:
    <XMLTemp>
    <Who>JoeSmith</Who>
    <Contact>Billy Joe</Contact>
    <telephone>123457980</telephone>	
    <PostCode>XX1 2XX</PostCode>
    <When>01/01/2009</When>
    
    <Who>JoeSmith</Who>
    <Contact>Brenda George</Contact>
    <telephone>3216549870</telephone>	
    <PostCode>XX5 3XX</PostCode>
    <When>01/01/2009</When>
    
    <Who>KateLee</Who>
    <Contact>Iain Smith</Contact>
    <telephone>45687354189</telephone>	
    <PostCode>AB1 2XX</PostCode>
    <When>01/01/2009</When>
    </XMLTemp>
    So that's 3 records, 2 for JoeSmith and one for KateLee. I'm going to be using another program to email them, so I need them in the following format:

    Code:
    <XMLTemp>
    
    <Who>JoeSmith
    <Person>
    <Contact>Billy Joe</Contact>
    <telephone>123457980</telephone>	
    <PostCode>XX1 2XX</PostCode>
    <When>01/01/2009</When>
    </Person>
    
    <Person>
    <Contact>Brenda George</Contact>
    <telephone>3216549870</telephone>	
    <PostCode>XX5 3XX</PostCode>
    <When>01/01/2009</When>
    </Person>
    </Who>
    
    
    <Who>KateLee
    <Person>
    <Contact>Iain Smith</Contact>
    <telephone>45687354189</telephone>	
    <PostCode>AB1 2XX</PostCode>
    <When>01/01/2009</When>
    </Person>
    </Who>
    </XMLTemp>
    (If there's any case mistakes, I hand wrote this as an example, it'll all be good on the real version; also, line breaks are to make it easier to read)

    I know about the for-each code:
    Code:
    <xsl:for-each select="//XMLtemp[*****]">
    But I need help with filling in the [****]

    I'm guessing it'll start [Who=, but I can't figure out how to make it equal the currently selected 'who'.

    Thanks in advance
    Mandi
  • Dormilich
    Recognized Expert Expert
    • Aug 2008
    • 8694

    #2
    Code:
    <xsl:for-each select="//Who">
    will select JoeSmith's and KateLee's node, if that's what you mean...

    Comment

    • mandanarchi
      New Member
      • Sep 2008
      • 90

      #3
      Thanks Dormilich but that's not what I mean.
      I want to only select each 'Who' once, and have all the contacts related to them listed below like this:
      Code:
      JoeSmith
      Person 1
      Person 2
      KateGeorge
      Person 3

      I've got this much
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes" encoding="UTF-8" />
      <xsl:template match="/">
      <Who>
      	<xsl:value-of select="//XMLTemp1/Who" />
      	<xsl:for-each select="//XMLTemp1">
      		<Person>
      			<Contact><xsl:value-of select="Contact" /></Contact>
      			<telephone><xsl:value-of select="telephone" /></telephone>	
      			<PostCode><xsl:value-of select="PostCode" /></PostCode>
      			<When><xsl:value-of select="FollowUpOn" /></When>
      		</Person>
      	</xsl:for-each>
      </Who>
      </xsl:template>
      </xsl:stylesheet>
      Which gives me
      Code:
      <?xml version="1.0"?>
      <Who>JoeSmith
      	<Person>
      		<Contact>Billy Joe</Contact>
      		<telephone>123457980</telephone>
      		<PostCode>XX1 2XX</PostCode>
      		<When>01/01/2009</When>
      	</Person>
      </Who>
      I've used the for-each ones before, and it normally gives me all the information (3 persons in this case) but now it's just giving me one?
      I'm missing something and I can't put my finger on it >_<

      Comment

      • Dormilich
        Recognized Expert Expert
        • Aug 2008
        • 8694

        #4
        Originally posted by mandanarchi
        I've used the for-each ones before, and it normally gives me all the information (3 persons in this case) but now it's just giving me one?
        I'm missing something and I can't put my finger on it >_<
        you're looping over the root element, therefore you get only one entry.

        Comment

        • mandanarchi
          New Member
          • Sep 2008
          • 90

          #5
          I copied the line from a working code I have:
          Code:
          <xsl:for-each select="//XMLtemp[Suppliers='Advent']">
          The problem is that I don't know what to replace [Suppliers='Adve nt'] with. That's just a static 'if suppliers = Advent then show it', I need a 'if Who = currently selected who then show it'.. Does that make sense?

          Comment

          • mandanarchi
            New Member
            • Sep 2008
            • 90

            #6
            Obvious. 'current()' was what I needed.
            That plus a couple other minor edits and solved.
            Always seems obvious once I've already asked.
            Thanks folks

            Comment

            • jkmyoung
              Recognized Expert Top Contributor
              • Mar 2006
              • 2057

              #7
              I'm guessing you figured it out, but you should be looping on the Who nodes, not the base node.

              <xsl:for-each select="//XMLTemp1/Who">

              Comment

              • mandanarchi
                New Member
                • Sep 2008
                • 90

                #8
                Here's my working solution. Ta for the help guys =)

                Code:
                <?xml version="1.0" encoding="UTF-8"?>
                <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
                <xsl:output method="xml" indent="yes" encoding="UTF-8" />
                <xsl:template match="/">
                <ToEmail>
                <xsl:for-each select="//XMLTemp1[not(Who=preceding-sibling::XMLTemp1/Who)]/Who">
                	<Sales>
                	<who><xsl:value-of select="current()"/></who>
                		<xsl:for-each select="//XMLTemp1[Who=current()]">
                		<Person>
                			<Contact><xsl:value-of select="Contact" /></Contact>
                			<telephone><xsl:value-of select="telephone" /></telephone>	
                			<PostCode><xsl:value-of select="PostCode" /></PostCode>
                			<When><xsl:value-of select="FollowUpOn" /></When>
                		</Person>
                	</xsl:for-each>
                </Sales>
                  </xsl:for-each>
                </ToEmail>
                </xsl:template>
                </xsl:stylesheet>

                Comment

                Working...