Anyone could help me with this category problem?

L

Li Ming

Now I'm learning how to write xsl to transform an xml document. I am trapped
by a problem, and here's the sample xml document:

<category>
<cd type="pop">Pop music</cd>
<cd type="rock">Rock</cd>
<cd type="classical">Classical music</cd>
</category>

<cdshelf>
<disc name="CCC" cg="pop"/>
<disc name="BBB" cg="pop"/>
<disc name="AAA" cg="pop"/>
<disc name="DDD" cg="classical"/>
<disc name="EEE" cg="rock"/>
<disc name="FFF" cg="classcial"/>
<disc name="GGG" cg="pop"/>
</cdshelf>

I want the target html page like this:

Pop music:
1. CCC
2. BBB
3. AAA
4. GGG

Rock:
1. EEE

Classical music:
1. DDD
2. FFF


Can I achieve it using xslt? Thank you.
 
J

Joris Gillis

Tempore 20:24:12 said:
<category>
<cd type="pop">Pop music</cd>
<cd type="rock">Rock</cd>
<cd type="classical">Classical music</cd>
</category>

<cdshelf>
<disc name="CCC" cg="pop"/>
<disc name="BBB" cg="pop"/>
<disc name="AAA" cg="pop"/>
<disc name="DDD" cg="classical"/>
<disc name="EEE" cg="rock"/>
<disc name="FFF" cg="classcial"/>
<disc name="GGG" cg="pop"/>
</cdshelf>

I want the target html page like this:

Pop music:
1. CCC
2. BBB
3. AAA
4. GGG

Rock:
1. EEE

Classical music:
1. DDD
2. FFF


Can I achieve it using xslt?
absolutely, and in numerous ways.

Here's one sample:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput indent="yes" />

<xsl:key name="discByCat" match="cdshelf/disc" use="@cg"/>

<xsl:template match="category">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="cd">
<p>
<h1><xsl:apply-templates/>:</h1>
<ol>
<xsl:apply-templates select="key('discByCat',@type)"/>
</ol>
</p>
</xsl:template>

<xsl:template match="cdshelf"/>

<xsl:template match="disc">
<li>
<xsl:value-of select="@name"/>
</li>
</xsl:template>

</xsl:stylesheet>


regards,
 
L

Li Ming

Joris Gillis said:
Tempore 20:24:12, die Monday 28 February 2005 AD, hinc in foro

Yes it's perfect and thanks for your reply. But if the element of <category>
is the first element in the xml document, and I want it appear in the last
in my html file, what should I do? I mean, the xml is:

<shop name="myshop">
<category>
<cd type="pop">Pop music</cd>
<cd type="rock">Rock</cd>
<cd type="classical">Classical music</cd>
</category>

<welcome>Welcome to myshop</welcome>

<content>
<headline>Music CD</headline>
<cdshelf>
<disc name="CCC" cg="pop"/>
<disc name="BBB" cg="pop"/>
<disc name="AAA" cg="pop"/>
<disc name="DDD" cg="classical"/>
<disc name="EEE" cg="rock"/>
<disc name="FFF" cg="classcial"/>
<disc name="GGG" cg="pop"/>
</cdshelf>
</content>
</shop>

And I want the desired html web page to be:

Welcome to myshop

Music CD

Pop music:
1. CCC
2. BBB
3. AAA
4. GGG

Rock:
1. EEE

Classical music:
1. DDD
2. FFF

Because <category> element appears before <welcome> element, so it is
matched first and displayed before <welcome>. Can I display it in the order
that I like, just as the output above, without modifying the layout of the
xml document (even the element order)? Thank you.
 
J

Joris Gillis

Tempore 23:03:36 said:
Because <category> element appears before <welcome> element, so it is
matched first and displayed before <welcome>. Can I display it in the order
that I like, just as the output above, without modifying the layout of the
xml document (even the element order)? Thank you.

Yes, no problem at all.

Give this a try:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput indent="yes" />

<xsl:key name="discByCat" match="cdshelf/disc" use="@cg"/>

<xsl:template match="category"/>

<xsl:template match="welcome | headline">
<xsl:element name="h{count(ancestor::*)}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>

<xsl:template match="cdshelf">
<xsl:for-each select="ancestor::shop/category/cd">
<h3><xsl:apply-templates/>:</h3>
<ol>
<xsl:apply-templates select="key('discByCat',@type)"/>
</ol>
</xsl:for-each>
</xsl:template>

<xsl:template match="disc">
<li><xsl:value-of select="@name"/></li>
</xsl:template>

</xsl:stylesheet>


regards,
 
L

Li Ming

Here's one sample:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput indent="yes" />

<xsl:key name="discByCat" match="cdshelf/disc" use="@cg"/>

<xsl:template match="category">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="cd">
<p>
<h1><xsl:apply-templates/>:</h1>
<ol>
<xsl:apply-templates select="key('discByCat',@type)"/>
</ol>
</p>
</xsl:template>

<xsl:template match="cdshelf"/>

<xsl:template match="disc">
<li>
<xsl:value-of select="@name"/>
</li>
</xsl:template>

</xsl:stylesheet>


regards,

Thank you again for your help, that helped me a lot. All the problems are
history now.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top