xsl-list
[Top] [All Lists]

Re: This could be simple, but not for me!

2004-05-25 11:05:54
Andrew, thanks again. You are right, there is just one <City> per
<Community> but I did not manage to get the right result with the modified
stylesheet. 

Here is the source again, now with two identical <Detail no> for City1:

<Root>
    <Community>
        <City>City1</City>
        <A>
            <B>
                <Name>Name1</Name>
                <Info>
                    <Detail no="100">Red</Detail>
                </Info>
            </B>
            <B>
                <Name>Name2</Name>
                <Info>
                    <Detail no="200">Blue</Detail>
                </Info>
            </B>
            <B>
                <Name>Name3</Name>
                <Info>
                    <Detail no="300">Green</Detail>
                </Info>
            </B>
             <B>
                <Name>Name7</Name>  <-----one more no="300" for City1
                <Info>
                    <Detail no="300">Green</Detail>
                </Info>
            </B>
        </A>
    </Community>
    <Community>
        <City>City2</City>
        <A>
            <B>
                <Name>Name4</Name>
                <Info>
                    <Detail no="100">Red</Detail>
                </Info>
            </B>
            <B>
                <Name>Name5</Name>
                <Info>
                    <Detail no="200">Blue</Detail>
                </Info>
            </B>
            <B>
                <Name>Name6</Name>
                <Info>
                    <Detail no="400">Yellow</Detail>
                </Info>
            </B>
        </A>
    </Community>
</Root>


...and this is the stylesheet:

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

<xsl:key name="details" match="Detail" use="concat(@no,'/',.)"/>
<xsl:key name="cities" match="City" use="."/>


<xsl:output method='html' version='1.0' encoding='iso-8859-1' indent='no'/>


<xsl:template match="/">
  <root>
    <xsl:apply-templates select="//Detail[generate-id() =
generate-id(key('details',concat(@no,'/',.))[1])]"/>
  </root>
</xsl:template>

<xsl:template match="Detail">
  <div detail="{concat(@no,', ',.)}">
    <xsl:for-each select="key('details',concat(@no,'/',.))">
      <span>

<xsl:if test="generate-id(ancestor::Community/City) =
generate-id(key('cities',ancestor::Community/City)[1])">
        <xsl:value-of select="ancestor::Community/City"/>,<xsl:text/>
</xsl:if>
        <xsl:value-of select="parent::Info/preceding-sibling::Name"/>
      </span>
  </xsl:for-each>
  </div>
</xsl:template>


</xsl:stylesheet>


...and this is the result I get:

<root>
    <div detail="100, Red">
        <span>City1,Name1</span>
        <span>City2,Name4</span>
    </div>
    <div detail="200, Blue">
        <span>City1,Name2</span>
        <span>City2,Name5</span>
    </div>
    <div detail="300, Green">
        <span>City1,Name3</span>
        <span>City1,Name7</span>
    </div>
    <div detail="400, Yellow">
        <span>City2,Name6</span>
    </div>
</root>


...and finally this is the result I need:

<root>
    <div detail="100, Red">
        <span>City1</span>
        <span>Name1</span>
        <span>City2</span>
        <span>Name4</span>
    </div>
    <div detail="200, Blue">
        <span>City1</span>
        <span>Name2</span>
        <span>City2</span>
        <span>Name5</span>
    </div>
    <div detail="300, Green">
        <span>City1</span>      <----- only one City
        <span>Name3</span>
        <span>Name7</span>
    </div>
    <div detail="400, Yellow">
        <span>City2</span>
        <span>Name6</span>
    </div>
</root>


Is there still hope?
Kenny




Thanks, Andrew

This is very very close to what I need. But the city name has
to be there only once for all names like:


100, Red
    City1
        Name1
        Name10
        Name100
        ...etc

    City2
        Name4
        Name40
        ...

200, Blue
    City1
        Name2
        Name20
        ...

    City2
        Name5
        ...

300, Green
    City1
        Name3
        Name30
        Name300
        Name3000
        ...

400, Yellow
    City2
        Name6
        ...

Is that possible as well?


Sure, just add an extra key and an if test around the value-of to check
if it's the first occurance of that value:

<xsl:key name="cities" match="City" use="."/>

and the if test:

<xsl:if test="generate-id(ancestor::Community/City) =
generate-id(key('cities',ancestor::Community/City)[1])">
<span><xsl:value-of select="ancestor::Community/City"/></span>
</xsl:if>

Now, this might fail at the moment because I'm guessing at the structure
of your xml, if its anything other that one <City> per <Community> then
you will need to adjust it.

cheers
andrew

--+------------------------------------------------------------------
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>