Re: [xsl] complex numbering problem

Subject: Re: [xsl] complex numbering problem
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Fri, 12 Dec 2008 22:03:40 +0530
I seem to have read the requirements a bit differently than, Mike.
Below is the stylesheet I think should work.

This uses Muenchian technique to eliminate duplicates.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                       version="1.0">
		
  <xsl:output method="xml" indent="yes" />

  <xsl:key name="x" match="@start | @end" use="." />

  <xsl:template match="/">
    <time_order>
      <xsl:variable name="no-of-layers" select="count(//layer)" />
      <xsl:for-each select="//layer">
        <time_slot time_slot_id="ts{position()}" time_value="0"/>
      </xsl:for-each>
      <xsl:for-each select="(//@start | //@end)[generate-id() =
generate-id(key('x', .)[1])][not(. = '0')]">
        <xsl:sort select="." data-type="number"/>
	<time_slot time_slot_id="ts{$no-of-layers + position()}" time_value="{.}"/>
      </xsl:for-each>
    </time_order>
  </xsl:template>

</xsl:stylesheet>


On Fri, Dec 12, 2008 at 9:22 PM, Alexander Koenig
<Alexander.Koenig@xxxxxx> wrote:
> Hi all,
>
> I'm fairly new to XSL but after a couple of hours of googling and
> thinking about how to structure my xsl file differently I came here in
> the hope that someone can help me not using saxon:assign (I already
> learned that this would be a bad thing - but to be honest, I also cannot
> get it to work with my Oxygen 9.3 ;-)
>
> I'm using Oxygen 9.3 under SuSE Linux 10.0. XSL 1.0, Saxon 6.5.5
>
> The problem is as follows: I want to transform one kind of XML files
> into another kind using XSLT.
>
> This is how (the relevant part of) my source file looks like:
>
> <root>
> <layer l-id="l01">
> <meta m-id="m01">
> <desc><name>layer-interpretation</name><val>abc</val></desc>
> <desc><name>layer-type</name><val>some_type</val></desc>
> </meta>
> <event e-id="l01-001" start="0" end="17.499806"/>
> <event e-id="l01-002" start="17.499806" end="17.524455">XYZ</event>
> <event e-id="l01-003" start="17.524455" end="113.487545">XYZ</event>
> <event e-id="l01-004" start="113.487545" end="113.554857">XYZ</event>
> <event e-id="l01-005" start="113.554857" end="113.94197">XYZ</event>
> <event e-id="l01-006" start="113.94197" end="114.1085">XYZ</event>
> </layer>
> <layer l-id="l02">
> <meta m-id="m02">
> <desc><name>layer-interpretation</name><val>xyz</val></desc>
> <desc><name>layer-type</name><val>some_other_type</val></desc>
> </meta>
> <event e-id="l02-001" start="0" end="17.7997">XYZ</event>
> <event e-id="l02-002" start="17.7997" end="112.409813">XYZ</event>
> <event e-id="l02-003" start="112.409813" end="112.763921">XYZ</event>
> <event e-id="l02-004" start="112.763921" end="113.570947">XYZ</event>
> </layer>
> <!--some more layers-->
> </root>
>
> This is how I want my target file to look like:
>
> <time_order>
>    <time_slot time_slot_id="ts1" time_value="0"/>
>    <time_slot time_slot_id="ts2" time_value="0"/>
>    <time_slot time_slot_id="ts3" time_value="17.499806"/>
>    <time_slot time_slot_id="ts4" time_value="17.524455"/>
>    <time_slot time_slot_id="ts5" time_value="17.7997"/>
>    <time_slot time_slot_id="ts6" time_value="112.409813"/>
>    <time_slot time_slot_id="ts7" time_value="112.763921"/>
>    <time_slot time_slot_id="ts8" time_value="113.487545"/>
>    <time_slot time_slot_id="ts9" time_value="113.554857"/>
>    <time_slot time_slot_id="ts10" time_value="113.570947"/>
>    <time_slot time_slot_id="ts11" time_value="113.94197"/>
>    <time_slot time_slot_id="ts12" time_value="114.1085"/>
> </time_order>
>
> That means, I want every time index (even duplicates, because I need
> them later on) in a separate time_slot element. The time_slot elements
> should be sorted by the time_value in ascending order and should get a
> unique id, also in ascending order. I just cannot get the XSL structured
> in such a way that both attributes are in order. It's always one or the
> other, but never both. Or when I get both in order, I have duplicate
> time_slot_id's instead.
>
> My latest attempt looks like this:
>
> <xsl:template match="event" mode="timeslots">
>    <time_slot>
>        <xsl:attribute name="time_slot_id">
>            <xsl:text>ts</xsl:text>
>            <xsl:number level="any" value="position()"/>
>        </xsl:attribute>
>        <xsl:attribute name="time_value">
>            <xsl:value-of select="@start"/>
>        </xsl:attribute>
>    </time_slot>
>    <xsl:if test="count(following-sibling::event)=0">
>        <time_slot>
>            <xsl:attribute name="time_slot_id">
>                <xsl:text>ts</xsl:text>
>                <xsl:number level="any" value="position()"/>
>            </xsl:attribute>
>            <xsl:attribute name="time_value">
>                <xsl:value-of select="@end"/>
>            </xsl:attribute>
>        </time_slot>
>    </xsl:if>
> </xsl:template>
>
> With this, both attributes are (almost, but not quite - why?) in order,
> but I get duplicate IDs for the "end" attributes. The result looks like
> this:
>
> <time_order>
> ...
> <time_slot time_slot_id="ts1727" time_value="113.487545"/>
> <time_slot time_slot_id="ts1728" time_value="113.554857"/>
> <time_slot time_slot_id="ts1729" time_value="113.570521"/>
> <time_slot time_slot_id="ts1729" time_value="114.10741400000001"/>
> <time_slot time_slot_id="ts1730" time_value="113.791077"/>
> <time_slot time_slot_id="ts1730" time_value="114.10859000000001"/>
> <time_slot time_slot_id="ts1731" time_value="113.94197699999999"/>
> <time_slot time_slot_id="ts1731" time_value="114.10859000000001"/>
> </time_order>
>
> The only idea I have to fix this, is a variable which I increase every
> time I enter the if block and which is added to position() to form the
> ID. But XSL has no variables and so I'm kind of stuck.
>
> I hope one of the XSL experts out there can help me.
>
> kind regards
> Alex


-- 
Regards,
Mukul Gandhi

Current Thread