RE: [xsl] increasing variable?

Subject: RE: [xsl] increasing variable?
From: "Andreas L. Delmelle" <a_l.delmelle@xxxxxxxxxx>
Date: Sun, 7 Dec 2003 12:53:38 +0100
> -----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


Current Thread