xpath dynamic selection

C

Curantil

When I look at all the examples every selection like
select="child::item[@value>3]" has a constant value to test against ("3" in
this case).
Can't this be done with a variable? eg:
select="child::item[@value>$basevalue]"

Because I'm trying to create a structure like this...
usecase
->item(s) (kind of ordered list)
->alt (with @number parameter)
->alternativecourse
->alternative (with @number parameter)
->item(s)

the "alternative"s should get the itemnumber from the matching "alt"s.
It try to do this by calling the alts in item with:
<xsl:apply-templates match="alt">
<xsl:with-param name="step" select="$step"/>
</xsl:apply-templates>
with the $step number of the item
and in alternative:
<xsl:param name="start">
<xsl:value-of select="ancestor::*/*/alt[@number=$anumber]"/>
</xsl:param>
with $anumber the number of the alternative.

But it returns nothing. If I remove the "[@number=$anumber]" part it always
returns 1, so I guess it returns the first match.

I also don't understand how I can get the @step value from the alt.
adding /attribute::step after the */*/alt doesn't seem to work.

If there are better ways to do this, please let me know, because I don't
completly understand the reasoning after the xsl structure.


Thanks,

Wim Lemkens
 
M

Martin Honnen

Curantil said:
When I look at all the examples every selection like
select="child::item[@value>3]" has a constant value to test against ("3" in
this case).
Can't this be done with a variable? eg:
select="child::item[@value>$basevalue]"

Sure, why not, any XPath expression is possible, as long as the
environment allows you to declare and initialize variables. XSLT does that.
Because I'm trying to create a structure like this...
usecase
->item(s) (kind of ordered list)
->alt (with @number parameter)
->alternativecourse
->alternative (with @number parameter)
->item(s)

I am not sure what the above describes, is that meant to be the source
XML or part of your XSLT?
the "alternative"s should get the itemnumber from the matching "alt"s.
It try to do this by calling the alts in item with:
<xsl:apply-templates match="alt">
<xsl:with-param name="step" select="$step"/>
</xsl:apply-templates>
with the $step number of the item
and in alternative:
<xsl:param name="start">
<xsl:value-of select="ancestor::*/*/alt[@number=$anumber]"/>
</xsl:param> with $anumber the number of the alternative.

But it returns nothing. If I remove the "[@number=$anumber]" part it always
returns 1, so I guess it returns the first match.

I also don't understand how I can get the @step value from the alt.
adding /attribute::step after the */*/alt doesn't seem to work.

I couldn't follow you here, please post the relevant snippets of the
source XML you have, and what output you are looking for. Then include
your attempts of XSLT to solve that.
 
C

Curantil

On Sunday 11 July 2004 11:09, Jeni Tennison wrote:
Ok, I'll clearify my vague question with some real code. But it is
rather long.

This is the relevant part of the input:
<usecase>
<title>Zoek boek op</title>
<description>De gebruiker heeft gegevens van een bepaald boek dat hij wilt
ontlenen en wilt weten waar het boek zich bevindt in de
bibliotheek.</description>
<actor>De gebruiker vult in eventueel verschillende velden gegevens in over
een boek dat hij zoekt.</actor>
<system>
<alt>1</alt>
Het systeem geeft een overzicht van de verschillende boeken die
voldoen aan
de zoekterm
</system>
<actor>
<alt>2</alt>
De gebruiker kiest het boek dat hij wilt opvragen
</actor>
<system>
Het systeem geeft de gegevens van het gevonden boek weer.
</system>
<alternativecourses>
<alternative>
<system>
Er is maar 1 overeenkomstig resultaat : Het systeem geeft direct de
gegevens van het gevonden boek weer.
</system>
</alternative>
<alternative>
<actor>
De gebruiker kiest om te zoeken op nieuwe gegevens.
</actor>
<system>
Het systeem geeft de invulvelden terug weer. (terug van stap 1)
</system>
</alternative>
</alternativecourses>
</usecase>

The required output would be: (without debug info):

De gebruiker heeft gegevens van een bepaald boek dat hij wilt ontlenen
en wilt
weten waar het boek zich bevindt in de bibliotheek.

1 De gebruiker vult in eventueel verschillende velden gegevens in over een
boek dat hij zoekt.
2 Het systeem geeft een overzicht van de verschillende
boeken die voldoen aan
de zoekterm
3 De gebruiker kiest het boek dat hij wilt opvragen
4 Het systeem geeft de gegevens van het gevonden boek
weer. Het systeem geeft
de gegevens van het gevonden boek weer.

Alternatieve Paden
2 Er is maar 1 overeenkomstig resultaat : Het systeem
geeft direct de
gegevens van het gevonden boek weer.

<<(note this is the second alternative)>>
3 De gebruiker kiest om te zoeken op nieuwe gegevens.
4 Het systeem geeft de invulvelden terug weer. (terug van
stap 1)


And here are the important parts of xsl:
<xsl:template match="usecase">
<<snip: some numbering setup copied from orderedlist>>

<xsl:variable name="start">
<xsl:choose>
<xsl:when test="@continuation='continues'">
<xsl:call-template name="usecase-starting-number"/>
</xsl:when>
<xsl:when test="$pi-start != ''">
<xsl:value-of select="$pi-start"/>
</xsl:when>
<xsl:eek:therwise>1</xsl:eek:therwise>
</xsl:choose>
</xsl:variable>

<<snip: some numbering setup copied from orderedlist>>

<div class="{name(.)}">
<xsl:call-template name="anchor"/>

<xsl:if test="title">
<xsl:call-template name="formal.object.heading"/>
</xsl:if>
<table class="usecase">
<xsl:if test="description">
<xsl:apply-templates select="description"/>
</xsl:if>
<tr><td>
<ol>
<xsl:if test="$start != '1'">
<xsl:attribute name="start">
<xsl:value-of select="$start"/>
</xsl:attribute>
</xsl:if>
<<snip: some numbering setup copied from orderedlist>>
<xsl:apply-templates select="*[(self::actor
or self::system)]"/>
</ol>
</td></tr>
</table>
<xsl:apply-templates select="alternativecourses"/>
</div>

<xsl:apply-templates select="*[not(self::actor
or self::title
or self::alternativecourses
or self::description
or self::system)]"/>
</xsl:template>

<xsl:template match="usecase/actor">
<xsl:param name="ucid"/>
<li>
<xsl:attribute name="number">
<xsl:call-template name="usecase-step-number"/>
</xsl:attribute>
<xsl:variable name="step">
<xsl:call-template name="usecase-step-number"/>
</xsl:variable>

<div class="actor">
<xsl:apply-templates match="alt">
<xsl:with-param name="step" select="$step"/>
</xsl:apply-templates>
<xsl:apply-templates select="*[not(self::alt)]"/>
</div>
</li>
</xsl:template>

<xsl:template match="usecase/system">
<li>
<xsl:attribute name="number">
<xsl:call-template name="usecase-step-number"/>
</xsl:attribute>
<xsl:variable name="step">
<xsl:call-template name="usecase-step-number"/>
</xsl:variable>
<div class="system">
<xsl:apply-templates match="alt">
<xsl:with-param name="step" select="$step"/>
</xsl:apply-templates>
<xsl:apply-templates/>
</div>
</li>
</xsl:template>

<xsl:template match="alternativecourses">
Alternatieve Paden
<xsl:param name="node" select="."/>

<div class="{name(.)}">
<xsl:call-template name="anchor"/>

<xsl:if test="title">
<xsl:call-template name="formal.object.heading"/>
</xsl:if>
<table class="usecase">
<xsl:if test="description">
<xsl:apply-templates select="description"/>
</xsl:if>
<tr><td>
<ol>
<xsl:apply-templates match="alternativecourses/alternative">
</xsl:apply-templates>
</ol>
</td></tr>
</table>
</div>
</xsl:template>

<xsl:template match="alt">
<xsl:param name="step"/>

<xsl:param name="number">
<xsl:apply-templates/>
</xsl:param>
<!-- temporary debuginfo -->
ucid : <xsl:copy-of select="$ucid"/>
number : <xsl:copy-of select="$number"/>
step : <xsl:copy-of select="$step"/>
</xsl:template>

<xsl:template match="alternativecourses/alternative/actor">
<li>
<xsl:attribute name="number">
<xsl:call-template name="alternative-step-number"/>
</xsl:attribute>
<div class="actor">
<xsl:apply-templates/>
</div>
</li>
</xsl:template>

<xsl:template match="alternativecourses/alternative/system">
<li>
<xsl:attribute name="number">
<xsl:call-template name="alternative-step-number"/>
</xsl:attribute>
<div class="system">
<xsl:apply-templates/>
</div>
</li>
</xsl:template>

<xsl:template match="alternativecourses/alternative">
<xsl:param name="node" select="."/>
<xsl:param name="number">
<xsl:call-template name="alternative-number"/>
</xsl:param>

<!-- get the startignumber _problem is
here!!!!_ -->
<xsl:param name="start">
<xsl:value-of
select="ancestor::../../*/alt[@number=current()/@number]"/>
</xsl:param>

<!-- temporary debug info -->
anumber : <xsl:copy-of select="$number"/>
step : <xsl:copy-of select="$start"/>

<!-- generate the new list -->
<xsl:variable name="pi-start">
<xsl:call-template name="dbhtml-attribute">
<xsl:with-param name="pis"
select="processing-instruction('dbhtml')"/>
<xsl:with-param name="attribute" select="'start'"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="numeration">
<xsl:call-template name="list.numeration"/>
</xsl:variable>

<xsl:variable name="type">
<xsl:choose>
<xsl:when test="$numeration='arabic'">1</xsl:when>
<xsl:when test="$numeration='loweralpha'">a</xsl:when>
<xsl:when test="$numeration='lowerroman'">i</xsl:when>
<xsl:when test="$numeration='upperalpha'">A</xsl:when>
<xsl:when test="$numeration='upperroman'">I</xsl:when>
<!-- What!? This should never happen -->
<xsl:eek:therwise>
<xsl:message>
<xsl:text>Unexpected numeration: </xsl:text>
<xsl:value-of select="$numeration"/>
</xsl:message>
<xsl:value-of select="1"/>
</xsl:eek:therwise>
</xsl:choose>
</xsl:variable>

<div class="{name(.)}">
<xsl:call-template name="anchor"/>
<tr><td>
<ol>
<xsl:if test="$start != '1'">
<xsl:attribute name="start">
<xsl:value-of select="$start"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="$numeration != ''">
<xsl:attribute name="type">
<xsl:value-of select="$type"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@spacing='compact'">
<xsl:attribute name="compact">
<xsl:value-of select="@spacing"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="*[(self::actor
or self::system)]"/>
</ol>
</td></tr>
</div>

<xsl:apply-templates select="*[not(self::actor
or self::title
or self::description
or self::system)]"/>
</xsl:template>

<xsl:template name="usecase-step-number">
<!-- context node must be a system or actor in a usecase -->
<xsl:param name="node" select="."/>

<xsl:choose>
<xsl:when test="$node/@override">
<xsl:value-of select="$node/@override"/>
</xsl:when>
<xsl:when test="$node/preceding-sibling::*[(self::system or
self::actor)]">
<xsl:variable name="pnum">
<xsl:call-template name="usecase-step-number">
<xsl:with-param name="node"
select="$node/preceding-sibling::*[(self::system or self::actor)][1]"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$pnum + 1"/>
</xsl:when>
<xsl:eek:therwise>
<xsl:call-template name="usecase-starting-number">
<xsl:with-param name="list" select="parent::*"/>
</xsl:call-template>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>

<xsl:template name="usecase-starting-number">
<xsl:param name="list" select="."/>
<xsl:choose>
<xsl:when test="not($list/@continuation = 'continues')">1</xsl:when>
<xsl:eek:therwise>
<xsl:variable name="prevlist"
select="$list/preceding::usecase[1]"/>
<xsl:choose>
<xsl:when test="count($prevlist) = 0">2</xsl:when>
<xsl:eek:therwise>
<xsl:variable name="prevlength"
select="count($prevlist/listitem)"/>
<xsl:variable name="prevstart">
<xsl:call-template name="usecase-starting-number">
<xsl:with-param name="list" select="$prevlist"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$prevstart + $prevlength"/>
</xsl:eek:therwise>
</xsl:choose>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>

<xsl:template name="alternative-number">
<xsl:param name="node" select="."/>

<xsl:choose>
<xsl:when test="$node/@override">
<xsl:value-of select="$node/@override"/>
</xsl:when>
<xsl:when test="$node/preceding-sibling::alternative">
<xsl:variable name="pnum">
<xsl:call-template name="alternative-number">
<xsl:with-param name="node"
select="$node/preceding-sibling::alternative[1]"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$pnum + 1"/>
</xsl:when>
<xsl:eek:therwise>
1
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>

<xsl:template name="alternative-step-number">
<!-- context node must be a system or actor in alternative -->
<xsl:param name="node" select="."/>

<xsl:choose>
<xsl:when test="$node/@override">
<xsl:value-of select="$node/@override"/>
</xsl:when>
<xsl:when test="$node/preceding-sibling::*[(self::system or
self::actor)]">
<xsl:variable name="pnum">
<xsl:call-template name="usecase-step-number">
<xsl:with-param name="node"
select="$node/preceding-sibling::*[(self::system or self::actor)][1]"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$pnum + 1"/>
</xsl:when>
<xsl:eek:therwise>
<xsl:call-template name="usecase-starting-number">
<xsl:with-param name="list" select="parent::*"/>
</xsl:call-template>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>

I hope this code helps more to comprehend the question.
The problem is locate somewhere around line 210 of the mail. (I marked
it in comment)


Thanks,

Wim Lemkens
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top