Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old October 27th, 2006, 02:46 PM
Authorized User
 
Join Date: Oct 2006
Posts: 34
Thanks: 0
Thanked 0 Times in 0 Posts
Default XSLT issue to add commas to values

Hi,
I'm using XSLT 2.0 and I have the following problem.
This is a subset of the XML.

<Warehouse>
  <Box>
     <Color>Blue</Color>
     <Clothing>Shirt</Clothing>
  </Box>
   <Box>
     <Color>Blue</Color>
     <Clothing>Pants</Clothing>
  </Box>
  <Box>
     <Color>Brown</Color>
     <Clothing>Jacket</Clothing>
  </Box>
  <Box>
     <Color></Color> (NOTE: There is no value)
     <Clothing>Shoes</Clothing>
  </Box>
 <Box>
     <Color>White</Color>
     <Clothing>Socks</Clothing>
  </Box>
</Warehouse>

I like to create an XSLT that produce the following output (if we could ignore the proper English).
"Blue Shirt, Pants Brown Jacket, Shoes White Socks."

So far, I got it to produce the following wrong output.
"Blue Shirt, Blue Pants, Brown Jacket, Shoes, White Socks."

Here are my requirements:
   1. Put a comma at end of <Clothing> only if the <Color> of next <Clothing> is the same.
   2. If <Color> has blank value, then the <Color> is the same as the <Color> of the previous <Clothing>.
   3. If <Color> has the same value as previous <Color>, then don't output that <Color> value.
   4. End with a period (.).

I appreciate any help on this. I have been twisting my head for the last 3 weeks on this.
 
Old October 27th, 2006, 03:21 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

It's always useful with this kind of question if you can show your best attempt, because that makes it possible to see where your misunderstandings of the spec arose.

You've stated the rules very clearly and they translate very directly into XSLT template rules. They don't even need 2.0 facilities, though I've used them where appropriate.

  1. Put a comma at end of <Clothing> only if the <Color> of next <Clothing> is the same.

<xsl:template match="Clothing">
  <xsl:value-of select="."/>
  <xsl:if test="../Color = ../following-sibling::Box[1]/Color">,</xsl:if>
</xsl:template>

   2. If <Color> has blank value, then the <Color> is the same as the <Color> of the previous <Clothing>.

I'm not sure if this rule should be applied before Rule 1, or if it only affects Rule 3. But in 2.0, try

<xsl:function name="f:color" as="xs:string">
  <xsl:param name="box" as="xs:element(Box)"/>
  <xsl:sequence select="if ($box/Color eq '') then $box/preceding-sibling::Box[1]/Color else $box/Color"/>
</xsl:function>

and then use f:color(box) in place of box/Color where appropriate

   3. If <Color> has the same value as previous <Color>, then don't output that <Color> value.

<xsl:template match="Color">
  <xsl:if test="not(f:folor(..) = f:color(../preceding-sibling::Box[1])">
    <xsl:value-of select="f:color(..)"/>

   4. End with a period (.).

<xsl:template match="Warehouse">
  <xsl:apply-templates/>
  <xsl:text>.</xsl:text>
</xsl:template>



Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old October 31st, 2006, 11:27 AM
Authorized User
 
Join Date: Oct 2006
Posts: 34
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Appreciate your help, mhkay.

I just got a notice from my boss to write the style sheet in XSLT 1.0 instead of XSLT 2.0. Would you transform your amazing solutions to rules 2 and 3 using XSLT 1.0 instead of XSLT 2.0.

I forgot to mention additional info to Rule 2.
"If <Color> has blank value, then the <Color> is the same as the <Color> of the previous <Clothing>. If previous <Color> has a blank value and it is the first <Color>, then that value is default to White."

Example 1:
<Warehouse>
  <Box>
     <Color></Color> (Note: Default is white)
     <Clothing>Shirt</Clothing>
  </Box>
   <Box>
     <Color></Color>
     <Clothing>Pants</Clothing>
  </Box>
   <Box>
     <Color>White</Color>
     <Clothing>Socks</Clothing>
  </Box>
<Warehouse>

Output of example 1 should be:
"White Shirt, Pants, Socks."

Example 2:
<Warehouse>
  <Box>
     <Color></Color> (Note: Default is white)
     <Clothing>Shirt</Clothing>
  </Box>
   <Box>
     <Color>Blue</Color>
     <Clothing>Pants</Clothing>
  </Box>
   <Box>
     <Color></Color>
     <Clothing>Socks</Clothing>
  </Box>
<Warehouse>

Output of example 2 should be:
"White Shirt Blue Pants, Socks."


Again greatly appreciate your help.
 
Old October 31st, 2006, 12:04 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

If your boss wants it done the expensive way, how big is her budget?

Actually, it's not that difficult, you just have to use a template rule in a particular mode rather than using a function.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
XSLT Template Issue saravanan.k XSLT 2 March 14th, 2007 06:41 AM
add values austinf XSLT 1 August 29th, 2006 06:08 AM
XSLT, add attribute ik XSLT 6 August 22nd, 2006 11:03 AM
How do I add up values in an array? Lucy Classic ASP Basics 6 May 31st, 2005 05:26 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.