xsl-list
[Top] [All Lists]

RE: increasing variable?

2003-12-07 04:53:38
-----Original Message-----
From: chris poppe

What im trying to do here is to halve ( sorry for my english, I
mean divide
by 2) the length of the Substreams. Offcourse the positions should be
altered too and here comes the problem. I thought i could declare
a variable
'position'  initiate it at 134 and every time I come across a
substream or
mv I just add the length but as Ive understood you cant just change your
variables?


Not entirely true... there is actually something as 'scope'. In essence, you
are right that variables declared at the top-level of the stylesheet can't
be modified during the transformation.

Suppose you have this at the top of your stylesheet

<xsl:variable name="start" select="134" />

Then you can't change the value of the start var, but you can use it in all
computations.

hope anyone can help me out here, every suggestion is welcome,


Hard to say without seeing more of your XML. Questions arising are: Are the
MV_interior nodes always in between two SUBSTR nodes? How many of these can
be in one file? In what variation(s)?

For now, all I can see is :

The real difficulty is that you can't use the computed values from the
result nodes (otherwise it would be rather easy... just pick up the modified
values from the previous '*_interior' and use these to compute the new
offset). Another difficulty I see is that, just because you have to compute
using the original values, for the MV_interior, you would have to compute
the offset like (pseudocode) :

134 + (sumofsizes(previous SUBSTREAM_interiors) * 0.5) +
(sumofsizes(previous MV_interiors))
+ (2 * count(previous SUBSTREAM_interiors)

But the sizes would have to be decoded from the string values first... which
would make using the sum() function quite awkward.

I'm personally thinking in the direction of a two-pass solution here:

- first transform the source so that each of the *_interior elements have
two subelements <offset> and <size> (as that would be a cake-walk AIW, I'll
leave this as an exercise...)

- then, on the intermediate XML, you could probably perform the necessary
calculations on the preceding:: axes with more ease

Attempt:

<!-- for all nodes (except SUBSTREAM_interior and MV_interior), you just
want the identity transform -->

<xsl:template match="node()">
  <xsl:copy>
    <xsl:apply-templates select="*" />
  </xsl:copy>
</xsl:template>

<!-- for stuff and MV_end, you want to copy the content as well -->

<xsl:template match="stuff | MV_end">
  <xsl:copy-of select="." />
</xsl:template>


<!-- for the very first SUBSTREAM_interior -->

<xsl:template match="//SUBSTR[1]/SUBSTREAM[1]/SUBSTREAM_interior[1]" />
  <xsl:copy>
    <xsl:value-of select="number($start)" /> <!-- alt. use 'offset' here -->
    <xsl:text> </xsl:text>
    <xsl:value-of select="size * 0.5" />
  </xsl:copy>
</xsl:template>

<!-- you want to 'halve' the SUBSTREAM_interior size, but only when it's in
a SUBSTR with multiple SUBSTREAMs (correct? --in your example the last one
isn't)

for the SUBSTREAM_interiors that are not in the first SUBSTREAM of the
surrounding SUBSTR; these are the easiest -->

<xsl:template match="//SUBSTR[count(SUBSTREAM) &gt;
1]/SUBSTREAM[position()!=1]/SUBSTREAM_interior">
  <xsl:copy>
    <xsl:value-of select="preceding::SUBSTREAM_interior[1]/offset
                        + (sum(preceding::SUBSTREAM_interior[1]/size) * 0.5)
                        + 2" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="size * 0.5" />
  </xsl:copy>
</xsl:template>

<!-- for the MV_interiors, and the SUBSTREAM_interiors in a SUBSTR with only
one SUBSTREAM something like -->

<xsl:template match="MV_interior | //SUBSTR[count(SUBSTREAM) =
1]/SUBSTREAM/SUBSTREAM_interior">

  <xsl:copy>
    <xsl:value-of select="number($start)
          + (sum(preceding::SUBSTR[count(SUBSTREAM) &gt;
1]/SUBSTREAM/SUBSTREAM_interior/size)
            + (2 * count(preceding::SUBSTREAM_interior))) * 0.5
          + (sum(preceding::SUBSTR[count(SUBSTREAM) =
1]/SUBSTREAM/SUBSTREAM_interior/size))
          + (sum(preceding::MV_interior/size))" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="size" />
  </xsl:copy>
</xsl:template>

<!-- for the first SUBSTREAM_interior in a SUBSTR with more than one
SUBSTREAM, the same except for the size -->

<xsl:template match="//SUBSTR[count(SUBSTREAM) &gt;
1]/SUBSTREAM[1]/SUBSTREAM_interior">

  <xsl:copy>
    <xsl:value-of select="number($start)
          + (sum(preceding::SUBSTR[count(SUBSTREAM) &gt;
1]/SUBSTREAM/SUBSTREAM_interior/size)
            + (2 * count(preceding::SUBSTREAM_interior))) * 0.5
          + (sum(preceding::SUBSTR[count(SUBSTREAM) =
1]/SUBSTREAM/SUBSTREAM_interior/size))
          + (sum(preceding::MV_interior/size))" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="size * 0.5" />
  </xsl:copy>

</xsl:template>


Hope this helps!

Cheers,

Andreas


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



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