Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > xsl totals composed from variables

Reply
Thread Tools

xsl totals composed from variables

 
 
the_jos
Guest
Posts: n/a
 
      11-03-2006
Dear reader,

I am trying some things with xml/xsl and cannot find a solution for
what I would like to do.

I have 2 base items with name and price and two that are composed of
base two (given name and quantity).
The composition never changes, only the price can change.
I can calculate the total value (price*quantity) with a for-each loop
(using xsl:key) for each set of components, listing below.

But now I want to calculate the total value of the components used in
the composed items.

I have looked into a 'loop' template, but this does not give the
results I want.
I tried various layouts, but only get a NaN value or the original value
passed to the loop.

I inserted the loop call right after I got the value p
(price*quantity).

Could someone point me to a working solution?

Thanks

Jos


------- loop template -----------
<xsl:template name="loop">
<xslaram name="pr"/>
<xslaram name="t" select="0"/> <!-- not sure about this one -->
<xsl:choose>
<xsl:when test="$pr">
<xsl:call-template name="loop">
<xsl:with-param name="t" select="$pr+$t"/>
</xsl:call-template>
</xsl:when>
<xsltherwise>
<xsl:value-of select="$t" />
</xsltherwise>
</xsl:choose>

</xsl:template>


Call:
<xsl:call-template name="loop">
<xsl:with-param name="pr" select="$p"/>
</xsl:call-template>



---- working code -----
<xsl:stylesheet xmlnssl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xslutput method="xml" omit-xml-declaration="yes"/>
<xsl:key name="comp" match="item" use="name" />
<xsl:template match="/">
<table border="1">
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="item">
<tr><td><xsl:value-of select="name" /> </td>
<td><xsl:value-of select="price" /></td>
<xsl:for-each select="component">
<td><xsl:value-of select="cname" /></td>
<td><xsl:value-of select="quantity" /></td>
<xsl:variable name="cn" select="cname" />
<xsl:variable name="q" select="quantity" />

<xsl:for-each select="key('comp', $cn)">
<xsl:variable name="p" select="price*$q" />
<td><xsl:value-of select="$p"/></td>
</xsl:for-each>

<!-- <xsl:value-of select="quantity" /> -->
</xsl:for-each>
</tr>
</xsl:template>

</xsl:stylesheet>

---- Sample XML ----

<items>
<item>
<name>A</name>
<price>10</price>
</item>
<item>
<name>B</name>
<price>20</price>
</item>
<item>
<name>C</name>
<price>10</price>
<component>
<cname>A</cname>
<quantity>2</quantity>
</component>
<component>
<cname>B</cname>
<quantity>5</quantity>
</component>
</item>
<item>
<name>D</name>
<price>10</price>
<component>
<cname>A</cname>
<quantity>2</quantity>
</component>
<component>
<cname>B</cname>
<quantity>5</quantity>
</component>
</item>
</items>

 
Reply With Quote
 
 
 
 
Dimitre Novatchev
Guest
Posts: n/a
 
      11-04-2006
Very unclear explanation -- try to provide a better one.

Cheers,
Dimitre Novatchev


"the_jos" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
> Dear reader,
>
> I am trying some things with xml/xsl and cannot find a solution for
> what I would like to do.
>
> I have 2 base items with name and price and two that are composed of
> base two (given name and quantity).
> The composition never changes, only the price can change.
> I can calculate the total value (price*quantity) with a for-each loop
> (using xsl:key) for each set of components, listing below.
>
> But now I want to calculate the total value of the components used in
> the composed items.
>
> I have looked into a 'loop' template, but this does not give the
> results I want.
> I tried various layouts, but only get a NaN value or the original value
> passed to the loop.
>
> I inserted the loop call right after I got the value p
> (price*quantity).
>
> Could someone point me to a working solution?
>
> Thanks
>
> Jos
>
>
> ------- loop template -----------
> <xsl:template name="loop">
> <xslaram name="pr"/>
> <xslaram name="t" select="0"/> <!-- not sure about this one -->
> <xsl:choose>
> <xsl:when test="$pr">
> <xsl:call-template name="loop">
> <xsl:with-param name="t" select="$pr+$t"/>
> </xsl:call-template>
> </xsl:when>
> <xsltherwise>
> <xsl:value-of select="$t" />
> </xsltherwise>
> </xsl:choose>
>
> </xsl:template>
>
>
> Call:
> <xsl:call-template name="loop">
> <xsl:with-param name="pr" select="$p"/>
> </xsl:call-template>
>
>
>
> ---- working code -----
> <xsl:stylesheet xmlnssl="http://www.w3.org/1999/XSL/Transform"
> version="1.0">
> <xslutput method="xml" omit-xml-declaration="yes"/>
> <xsl:key name="comp" match="item" use="name" />
> <xsl:template match="/">
> <table border="1">
> <xsl:apply-templates/>
> </table>
> </xsl:template>
> <xsl:template match="item">
> <tr><td><xsl:value-of select="name" /> </td>
> <td><xsl:value-of select="price" /></td>
> <xsl:for-each select="component">
> <td><xsl:value-of select="cname" /></td>
> <td><xsl:value-of select="quantity" /></td>
> <xsl:variable name="cn" select="cname" />
> <xsl:variable name="q" select="quantity" />
>
> <xsl:for-each select="key('comp', $cn)">
> <xsl:variable name="p" select="price*$q" />
> <td><xsl:value-of select="$p"/></td>
> </xsl:for-each>
>
> <!-- <xsl:value-of select="quantity" /> -->
> </xsl:for-each>
> </tr>
> </xsl:template>
>
> </xsl:stylesheet>
>
> ---- Sample XML ----
>
> <items>
> <item>
> <name>A</name>
> <price>10</price>
> </item>
> <item>
> <name>B</name>
> <price>20</price>
> </item>
> <item>
> <name>C</name>
> <price>10</price>
> <component>
> <cname>A</cname>
> <quantity>2</quantity>
> </component>
> <component>
> <cname>B</cname>
> <quantity>5</quantity>
> </component>
> </item>
> <item>
> <name>D</name>
> <price>10</price>
> <component>
> <cname>A</cname>
> <quantity>2</quantity>
> </component>
> <component>
> <cname>B</cname>
> <quantity>5</quantity>
> </component>
> </item>
> </items>
>



 
Reply With Quote
 
 
 
 
Joe Kesselman
Guest
Posts: n/a
 
      11-04-2006
Dimitre Novatchev wrote:
> Very unclear explanation -- try to provide a better one.


For example: Show us what output you're trying to get, and explain
specifically how that output was obtained.

Or, if you want to figure this out yourself: Put some output (either
document output, or xsl:message calls) into your loop template,
displaying the values of your variables. The first thing you'll discover
is that because you failed to explicitly pass $pr into the recursion, it
isn't set the second time through, so your "loop" isn't doing much looping.


--
() ASCII Ribbon Campaign | Joe Kesselman
/\ Stamp out HTML e-mail! | System architexture and kinetic poetry
 
Reply With Quote
 
Joe Kesselman
Guest
Posts: n/a
 
      11-04-2006
For example:

<xsl:stylesheet xmlnssl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xslutput method="xml" omit-xml-declaration="yes"/>
<xsl:key name="comp" match="item" use="name" />
<xsl:template match="/">
<table border="1">
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="item">
<tr><td><xsl:value-of select="name" /> </td>
<td><xsl:value-of select="price" /></td>
<xsl:for-each select="component">
<td><xsl:value-of select="cname" /></td>
<td><xsl:value-of select="quantity" /></td>
<xsl:variable name="cn" select="cname" />
<xsl:variable name="q" select="quantity" />

<xsl:for-each select="key('comp', $cn)">
<xsl:variable name="p" select="price*$q" />
<td><xsl:value-of select="$p"/></td>

---------------------------
Test (must be within scope of the $p variable):

<xsl:call-template name="loop">
<xsl:with-param name="pr" select="$p"/>
</xsl:call-template>
---------------------------

</xsl:for-each>

<!-- <xsl:value-of select="quantity" /> -->
</xsl:for-each>
</tr>

</xsl:template>

<xsl:template name="loop">
<xslaram name="pr"/>
<xslaram name="t" select="0"/>
<xsl:message>pr=<xsl:value-of select="$pr"/>, t=<xsl:value-of
select="$t"/></xsl:message>
<xsl:choose>
<xsl:when test="$pr">
<xsl:call-template name="loop">
<xsl:with-param name="t" select="$pr+$t"/>
<!-- I presume you meant to add: -->
<xsl:with-param name="pr" select="$pr -1"/>
</xsl:call-template>
</xsl:when>
<xsltherwise>
<xsl:value-of select="$t" />
</xsltherwise>
</xsl:choose>

</xsl:template>
</xsl:stylesheet>

--
() ASCII Ribbon Campaign | Joe Kesselman
/\ Stamp out HTML e-mail! | System architexture and kinetic poetry
 
Reply With Quote
 
the_jos
Guest
Posts: n/a
 
      11-05-2006

Joe Kesselman wrote:
> Dimitre Novatchev wrote:
>
> For example: Show us what output you're trying to get, and explain
> specifically how that output was obtained.
>
> Or, if you want to figure this out yourself: Put some output (either
> document output, or xsl:message calls) into your loop template,
> displaying the values of your variables. The first thing you'll discover
> is that because you failed to explicitly pass $pr into the recursion, it
> isn't set the second time through, so your "loop" isn't doing much looping.


Joe,

Thanks for the reply.
I'll look into your example and your surgestion above tomorrow (it's
getting late here in Europe).

I'm trying to get a better understanding about xml/xsl and am trying to
do that with something that interests me. So I am trying to build a xml
document that determines the minimum net. value of some components in
an online game.
I can do this in a program language (like java), but am looking for a
more code-independent solution. I then found out that xml/xsl does not
handle variables the way a program language does. But that's not
entirely strange, given the nature of xsl.

Let's give a somewhat real-life example:

Lets say I want a table set.

I know the components are:
4 chairs and one table.
A chair is 4 legs and one chair_top.
A table is 4 legs and one table_top.
A table_top is 2 hours of work and 2 wood. Or 100 euro's
A chair_top is 1 hour of work and 1 wood. Or 50 euro's.
Legs are 1 hour of work and 1 wood. Or 25 euro's.

Wood is 5 euro's, work is 20 euro's.
Prices vary, but components remain the same.

For my question, I just wanted to determine the value of legs (25),
chair_top (25) and table_top (50) given the price of wood and work.

I figured out that when I have those values, I can determine the
minimum value of those components.
Given that, I can determine the minimum value of chair and table and
with those the minimum value of 'table_set'.
There willl be various combinations for table_set (like 6 chairs/one
table, 4 chairs /2 tables).
So I figured to make 2 xml sets.
One for each final table_set. This one contains the set name and the
number of tables/chairs.
And one for the base components (in this case wood and work) and the
various combined components (like the legs and tops and ultimate
tables/chairs).

The table_set will inherent / import the data from the list of
base/combined components, which are 'processed' so they will only give
the minimum values.
So when I look up 'table', it calculates building legs and table_top,
determines if building or buying is cheaper, calculate the minimum
value for table based on those results and returns that value.

This would lead to a layout like:
Table_set 1: Tables=1 Chairs=4 Price=650 (150+500)
Table_set 2: Tables=2 Chairs=6 Price=900 (150+750)

Now that I'm thinking about it, is it best to handle the 'combined'
components in the xsl file (put price in xml file and the 'combining
logic' in xsl). Or should I just leave it the way it is right now?

I think I will be working on this idea for the next weeks, but that's
part of learning something new.
It won't be a big xml set for the base components.
I think there's 20 base materials (like wood and work) and 15 combined
(like legs/tops).
The 'table' and 'chair' components are rare, I think there are about 4.
So I figured handling this with xsl should not cause too much resource
problems.

 
Reply With Quote
 
Joe Kesselman
Guest
Posts: n/a
 
      11-06-2006
the_jos wrote:
> I then found out that xml/xsl does not
> handle variables the way a program language does. But that's not
> entirely strange, given the nature of xsl.


Actually, XSLT handles variables very much the same way other
nonprocedural programming langauges do -- single-assignment, lexically
scoped.

> For my question, I just wanted to determine the value of legs (25),
> chair_top (25) and table_top (50) given the price of wood and work.


This is as much a data-representation problem as a stylesheet problem.
If your data hierarchy matches the structural hierarchy, gathering the
structured information becomes much easier -- for example, if the data
is something like

<set>
<table quantity="1">
<top quantity="1" hours="2" wood="2" price="100"/>
<leg quantity="4" hours="1" wood="1" price="25"/>
</table>
<chair quantity="4">
<top quantity="1" hours="1" wood="1" price="50"/>
<leg quantity="4" hours="1" wood="1" price="25"/>
</chair>
</set>

then this becomes a fairly straightforward recursive
multiply-and-accumulate problem. (Value at any node is sum of values of
its children times their quantity, plus its own value if any.) That
isn't necessarily the best solution; there are several other possible
ways to structure this.

Note that this provides all the information in a single document. If you
really wanted to separate the values from the

Picking the minimum of two results is simple once you've got the values,
of course.


This isn't a typical use of XSLT, of course. It's more typical of what
one will do using XQuery... but XQuery and XSLT 2.0 are essentially the
same language with different syntax.


--
() ASCII Ribbon Campaign | Joe Kesselman
/\ Stamp out HTML e-mail! | System architexture and kinetic poetry
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Running totals in gridview (when you have many totals required) =?Utf-8?B?Um9iZXJ0IENoYXBtYW4=?= ASP .Net 3 02-16-2007 12:03 PM
XSL Question tp xsl:for-each and xsl:variable schaf@2wire.ch XML 1 05-27-2005 09:25 PM
Using protected with composed class in an implented interface? iksrazal Java 2 03-08-2005 11:37 AM
Smallville not composed for widescreen Waterperson77 DVD Video 67 12-16-2003 03:16 AM
Defining composed keys [XSD] Francesc Guim Bernat XML 0 07-29-2003 07:49 AM



Advertisments