xsl-list
[Top] [All Lists]

Re: Group and compare data

2004-10-07 01:22:17
Hi Thomas,

Here's an XSLT 1.0 solution:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
   <xsl:output method="text" encoding="utf-8"/>
   <xsl:template match="/">
       <xsl:apply-templates select="//Forhandler[navn]"/>
   </xsl:template>
   <xsl:template match="Forhandler">
       <xsl:text>&#xa;</xsl:text>
       <xsl:value-of select="navn"/>
       <xsl:text>&#xa;</xsl:text>
<xsl:apply-templates select="*[starts-with(name(),'aabningstider')][1]" mode="recurse"/>
   </xsl:template>
   <xsl:template match="*" mode="recurse">
<xsl:param name="start-day" select="substring-after(name(),'aabningstider')"/> <xsl:variable name="this-day" select="substring-after(name(),'aabningstider')"/> <xsl:variable name="next" select="following-sibling::*[1][starts-with(name(),'aabningstider')]"/>
       <xsl:choose>
<xsl:when test="$next and normalize-space(.) = normalize-space($next/.)">
               <xsl:apply-templates select="$next" mode="recurse">
                   <xsl:with-param name="start-day" select="$start-day"/>
               </xsl:apply-templates>
           </xsl:when>
           <xsl:otherwise>
               <xsl:text>  </xsl:text>
               <xsl:if test="$start-day != $this-day">
                   <xsl:value-of select="$start-day"/>
                   <xsl:text>-</xsl:text>
               </xsl:if>
               <xsl:value-of select="$this-day"/>
               <xsl:text>  </xsl:text>
               <xsl:value-of select="normalize-space(.)"/>
               <xsl:text>&#xa;</xsl:text>
               <xsl:apply-templates select="$next" mode="recurse"/>
           </xsl:otherwise>
       </xsl:choose>
   </xsl:template>
</xsl:stylesheet>

It's not *that* tedious is it?  :)
Output (after fixing one "17: 30" in the input):

Dealer name
 Man-Fre  7:30 - 17:30
 Loer  10:00 - 14:00
 Soen  Efter aftale

Another dealer
 Man-Tors  07.30 - 17.30
 Fre  07.30 - 16.00
 Loer-Soen  Lukket

Note: if you control the structure of your input file, consider using a single element name
and putting the day names inside an attribute like this:

<aabningstider day="Man">7:30 - 17:30</aabningstider>
<aabningstider day="Tirs">7:30 - 17:30</aabningstider>
...

It makes selecting them quite a bit easier:
"*[starts-with(name(),'aabningstider')][1]" would become "aabningstider[1]"
"substring-after(name(),'aabningstider')" becomes "@day"

Best regards,
Anton


Verakso wrote:

I have som XML that looks like this:

<Forhandler>
        <Forhandler>
                <navn>Dealer name</navn>
                <email>mail(_at_)adress(_dot_)dk</email>
                <adresse>road 11</adresse>
                <postnr>9999</postnr>
                <by>city</by>
                <telefon>4444444</telefon>
                <aabningstiderMan>7:30 - 17:30</aabningstiderMan>
                <aabningstiderTirs>7:30 - 17: 30</aabningstiderTirs>
                <aabningstiderOns>7:30 - 17:30</aabningstiderOns>
                <aabningstiderTors>7:30 - 17:30</aabningstiderTors>
                <aabningstiderFre>7:30 - 17:30</aabningstiderFre>
                <aabningstiderLoer>10:00 - 14:00</aabningstiderLoer>
                <aabningstiderSoen>Efter aftale</aabningstiderSoen>
        </Forhandler>
        <Forhandler>
                <navn>Another dealer</navn>
                <email>another(_at_)adress(_dot_)dk</email>
                <adresse>another road</adresse>
                <postnr>5555</postnr>
                <by>big city</by>
                <telefon>5555555</telefon>
                <aabningstiderMan>07.30 - 17.30</aabningstiderMan>
                <aabningstiderTirs>07.30 - 17.30</aabningstiderTirs>
                <aabningstiderOns>07.30 - 17.30</aabningstiderOns>
                <aabningstiderTors>07.30 - 17.30</aabningstiderTors>
                <aabningstiderFre>07.30 - 16.00</aabningstiderFre>
                <aabningstiderLoer>Lukket</aabningstiderLoer>
                <aabningstiderSoen>Lukket</aabningstiderSoen>
        </Forhandler>
</Forhandler>

What I am trying to accomplish is to group the opening hours so they
look more nice.

For the first dealer the result would be:
Mon-Fre 7:30-17:30
Loer 10:00 - 14:00
Soen Efter aftale

For the second dealer the result would be:
Man-Tor 07.30 - 17.30
Fre 07.30 - 16.00
Loer-Soen Lukket

I have tried som xsl-choose loop, but I went sour in the complexity of
variations, what if a dealer have diffent opening hours every day of
the week.

So I thought, there must be at better approach on how to achieve this.
Is the use of keys a better approach, and if so, how?

/Thomas



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