| 1 |
<?xml version="1.0" encoding="ISO-8859-1"?> |
| 2 |
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://www.w3.org/2005/07/scxml" |
| 3 |
xmlns:Qt="http://www.qtsoftware.com scxml-ext"> |
| 4 |
<xsl:template name="smname"><xsl:choose><xsl:when test="string(/s:scxml/@name)=''"><xsl:value-of select="$target" /></xsl:when> |
| 5 |
<xsl:otherwise><xsl:value-of select="/sLscxml/@name" /></xsl:otherwise></xsl:choose> |
| 6 |
</xsl:template> |
| 7 |
<xsl:template name="comment"><xsl:if test="$comments"> |
| 8 |
/* |
| 9 |
<xsl:element name="{name()}"> |
| 10 |
<xsl:for-each select="@*"><xsl:attribute name="{name()}"> |
| 11 |
<xsl:value-of select="string()" /></xsl:attribute></xsl:for-each><xsl:value-of select="text()" /></xsl:element> |
| 12 |
*/ |
| 13 |
</xsl:if></xsl:template> |
| 14 |
<xsl:template mode="stateid" match="s:scxml|s:state|s:parallel|s:final|s:initial|s:history" priority="2"> |
| 15 |
<xsl:choose> |
| 16 |
<xsl:when test="name()='scxml'">this</xsl:when> |
| 17 |
<xsl:when test="string(@id) != ''" >state_<xsl:value-of select="@id" /></xsl:when> |
| 18 |
<xsl:otherwise>state_<xsl:value-of select="generate-id()" /></xsl:otherwise> |
| 19 |
</xsl:choose> |
| 20 |
</xsl:template> |
| 21 |
<xsl:template mode="execContext" match="s:if"> |
| 22 |
<xsl:call-template name="comment" /> |
| 23 |
if (<xsl:value-of select="@cond" />) { |
| 24 |
<xsl:apply-templates mode="execContext" /> |
| 25 |
} |
| 26 |
</xsl:template> |
| 27 |
<xsl:template mode="execContext" match="s:else"> |
| 28 |
<xsl:call-template name="comment" /> |
| 29 |
} else { |
| 30 |
</xsl:template> |
| 31 |
<xsl:template mode="execContext" match="s:elseif"> |
| 32 |
<xsl:call-template name="comment" /> |
| 33 |
} else if (<xsl:value-of select="@cond" />) { |
| 34 |
</xsl:template> |
| 35 |
<xsl:template mode="execContext" match="s:log"> |
| 36 |
<xsl:call-template name="comment" /> |
| 37 |
QDebug((QtMsgType)<xsl:if test="string(@level)=''">0</xsl:if><xsl:value-of select="@level" />) <xsl:if test="string(@label)!=''"><< "<xsl:value-of select="@label" />" </xsl:if><< <xsl:value-of select="@expr" />; |
| 38 |
</xsl:template> |
| 39 |
<xsl:template mode="execContext" match="s:assign"><xsl:call-template name="comment" /> |
| 40 |
<xsl:choose> |
| 41 |
|
| 42 |
<xsl:when test="string(@dataid) != ''"> |
| 43 |
set_<xsl:value-of select="@dataid" />(<xsl:value-of select="@expr" />); |
| 44 |
</xsl:when> |
| 45 |
<xsl:when test="string(@location) != ''"> |
| 46 |
<xsl:value-of select="@location" /> = (<xsl:value-of select="@expr" />); |
| 47 |
</xsl:when> |
| 48 |
</xsl:choose> |
| 49 |
</xsl:template> |
| 50 |
<xsl:template mode="execContext" match="s:raise|s:send"> |
| 51 |
<xsl:call-template name="comment" /> |
| 52 |
<xsl:choose> |
| 53 |
<xsl:when test="name()='raise' or @target='_internal'">postEvent(</xsl:when> |
| 54 |
<xsl:otherwise><xsl:if test="string(@id)!=''"> |
| 55 |
_eventSenders["<xsl:value-of select="@id" />"] = </xsl:if>new SCC_EventSender(this,<xsl:if test="string(@delay)=''">0</xsl:if> |
| 56 |
<xsl:value-of select="@delay" />, |
| 57 |
</xsl:otherwise> |
| 58 |
</xsl:choose> |
| 59 |
new QStateMachine::SignalEvent(<xsl:if |
| 60 |
test="string(@target)=''">this</xsl:if><xsl:value-of |
| 61 |
select="@target" />,metaObject()->indexOfSignal(QMetaObject::normalizedSignature("event_<xsl:value-of select="replace(@event,'\.','__')" /><xsl:if test="not(contains(@event,')'))">()</xsl:if>")),QVariantList()<xsl:for-each |
| 62 |
select="s:param"><xsl:text><![CDATA[<<]]></xsl:text> QVariant(<xsl:choose> |
| 63 |
<xsl:when test="string(@expr)!=''"><xsl:value-of select="@expr" /></xsl:when> |
| 64 |
<xsl:when test="string(@name)!=''">get_<xsl:value-of select="@name" />()</xsl:when> |
| 65 |
<xsl:otherwise><xsl:value-of select="text()" /></xsl:otherwise> |
| 66 |
</xsl:choose>) |
| 67 |
</xsl:for-each>)<xsl:if test="name()='raise' or @target='_internal'">,QStateMachine::HighPriority</xsl:if>); |
| 68 |
</xsl:template> |
| 69 |
<xsl:template mode="execContext" match="s:cancel"> |
| 70 |
<xsl:call-template name="comment" /><![CDATA[ |
| 71 |
{ |
| 72 |
QPointer<SCC_EventSender> es = _eventSenders["]]><xsl:value-of select="@id" />"]; |
| 73 |
if (es) |
| 74 |
es->cancel(); |
| 75 |
} |
| 76 |
</xsl:template> |
| 77 |
|
| 78 |
<xsl:template match="/"> |
| 79 |
#ifndef __SMCLASS_<xsl:call-template name="smname" />_H |
| 80 |
#define __SMCLASS_<xsl:call-template name="smname" />_H |
| 81 |
#include "QStateMachine" |
| 82 |
#include "QSignalTransition" |
| 83 |
#include "QTimer" |
| 84 |
#include "QMetaMethod" |
| 85 |
#include "QPointer" |
| 86 |
#include "QVariant" |
| 87 |
<xsl:if test="count(//s:final)!=0"> |
| 88 |
|
| 89 |
#include "QFinalState" |
| 90 |
</xsl:if> |
| 91 |
<xsl:if test="count(//s:history)!=0"> |
| 92 |
#include "QHistoryState" |
| 93 |
</xsl:if> |
| 94 |
#include "QHash" |
| 95 |
#include "QEventTransition" |
| 96 |
<xsl:if test="count(//s:log)!=0"> |
| 97 |
#include "QDebug" |
| 98 |
</xsl:if> |
| 99 |
<xsl:if test="count(//s:transition[string(@Qt:animation)!=''])!=0"> |
| 100 |
#include "QPropertyAnimation" |
| 101 |
</xsl:if> |
| 102 |
|
| 103 |
#define In(state) (configuration().contains(state_##state)) |
| 104 |
|
| 105 |
<xsl:value-of select="/s:scxml/Qt:cpp/text()" /> |
| 106 |
|
| 107 |
class SMClass_<xsl:call-template name="smname" />; |
| 108 |
<xsl:if test="count(//s:transition[string(@event)='' and string(@cond)=''])!=0"> |
| 109 |
class SCC_UnconditionalTransition : public QAbstractTransition |
| 110 |
{ |
| 111 |
public: |
| 112 |
SCC_UnconditionalTransition(QState* s) |
| 113 |
: QAbstractTransition(s) {} |
| 114 |
protected: |
| 115 |
void onTransition(QEvent *) {} |
| 116 |
bool eventTest(QEvent *) { return true; } |
| 117 |
}; |
| 118 |
</xsl:if> |
| 119 |
<xsl:if test="count(//s:send[string(@target)!='_internal'])!=0"> |
| 120 |
<![CDATA[ |
| 121 |
#define ARG_FROM_VAR(I) \ |
| 122 |
(acount > I \ |
| 123 |
? QGenericArgument(((QStateMachine::SignalEvent*)event)->arguments()[I].typeName(),((QStateMachine::SignalEvent*)event)->arguments()[I].data()) \ |
| 124 |
: QGenericArgument()) |
| 125 |
|
| 126 |
|
| 127 |
class SCC_EventSender : public QTimer |
| 128 |
{ |
| 129 |
Q_OBJECT |
| 130 |
private: |
| 131 |
QStateMachine* machine; |
| 132 |
QStateMachine::SignalEvent* event; |
| 133 |
public: |
| 134 |
SCC_EventSender(QStateMachine* m=NULL, int delay=0, QStateMachine::SignalEvent* e=NULL) : QTimer(m), machine(m), event(e) |
| 135 |
{ |
| 136 |
setInterval(delay); |
| 137 |
setSingleShot(true); |
| 138 |
connect(this,SIGNAL(timeout()),this,SLOT(send())); |
| 139 |
start(); |
| 140 |
} |
| 141 |
public Q_SLOTS: |
| 142 |
void cancel() { stop(); deleteLater(); } |
| 143 |
void send() { |
| 144 |
QVariantList args = event->arguments(); |
| 145 |
int acount = args.count(); |
| 146 |
event->sender()->metaObject()->method(event->signalIndex()).invoke(event->sender(), |
| 147 |
ARG_FROM_VAR(0),ARG_FROM_VAR(1),ARG_FROM_VAR(2),ARG_FROM_VAR(3),ARG_FROM_VAR(4), |
| 148 |
ARG_FROM_VAR(5),ARG_FROM_VAR(6),ARG_FROM_VAR(7),ARG_FROM_VAR(8),ARG_FROM_VAR(9)); |
| 149 |
deleteLater(); |
| 150 |
} |
| 151 |
}; |
| 152 |
]]></xsl:if> |
| 153 |
<xsl:if test="count(//s:transition[string(@cond) != '' or @event='*']) !=0"> |
| 154 |
namespace { |
| 155 |
<xsl:for-each select="//s:transition[string(@cond) != '' or @event='*']"> |
| 156 |
<xsl:call-template name="comment" /> |
| 157 |
class Transition_<xsl:value-of select="generate-id()" /> : public QSignalTransition |
| 158 |
{ |
| 159 |
SMClass_<xsl:call-template name="smname" />* stateMachine; |
| 160 |
public: |
| 161 |
Transition_<xsl:value-of select="generate-id()" />(QState* parent) |
| 162 |
: QSignalTransition(parent->machine(),<xsl:choose><xsl:when test="@event='*'">SIGNAL(destroyed())</xsl:when><xsl:otherwise>SIGNAL(event_<xsl:value-of select="@event" />)</xsl:otherwise></xsl:choose>,parent) |
| 163 |
,stateMachine((SMClass_<xsl:call-template name="smname" />*)parent->machine()) |
| 164 |
{ |
| 165 |
} |
| 166 |
|
| 167 |
protected: |
| 168 |
bool eventTest(QEvent* e); |
| 169 |
}; |
| 170 |
|
| 171 |
</xsl:for-each> |
| 172 |
}; |
| 173 |
</xsl:if> |
| 174 |
class SMClass_<xsl:call-template name="smname" /> : public QStateMachine |
| 175 |
{ |
| 176 |
Q_OBJECT |
| 177 |
<xsl:for-each select="//s:datamodel/s:data"> |
| 178 |
<xsl:call-template name="comment" /> |
| 179 |
Q_PROPERTY(<xsl:value-of select="concat(@Qt:type,' ')" /> <xsl:value-of select="@id" /> READ get_<xsl:value-of select="@id" /> WRITE set_<xsl:value-of select="@id" /> NOTIFY <xsl:value-of select="@id" />_changed) |
| 180 |
</xsl:for-each> |
| 181 |
<xsl:for-each select="//s:transition/Qt:animation"> |
| 182 |
<xsl:call-template name="comment" /> |
| 183 |
Q_PROPERTY(QPropertyAnimation* <xsl:value-of select="string()" /> READ anim_<xsl:value-of select="string()" /> WRITE setAnim_<xsl:value-of select="string()" />) |
| 184 |
</xsl:for-each> |
| 185 |
|
| 186 |
public: |
| 187 |
SMClass_<xsl:call-template name="smname" />(QObject* o = NULL) |
| 188 |
: QStateMachine(o) |
| 189 |
{ |
| 190 |
<xsl:for-each select="//s:datamodel/s:data[string-length(concat(string(text()),string(@expr)))!=0]"> |
| 191 |
<xsl:call-template name="comment" /> |
| 192 |
<xsl:if test="string(@expr) != ''"> |
| 193 |
_data.<xsl:value-of select="@id" /> = <xsl:value-of select="@expr"/><xsl:value-of select="text()"/>; |
| 194 |
</xsl:if> |
| 195 |
</xsl:for-each> |
| 196 |
} |
| 197 |
<xsl:for-each select="//s:state|//s:parallel|//s:initial"> |
| 198 |
<xsl:call-template name="comment" /> |
| 199 |
QState* <xsl:apply-templates mode="stateid" select="." />;</xsl:for-each> |
| 200 |
<xsl:for-each select="//s:final"> |
| 201 |
<xsl:call-template name="comment" /> |
| 202 |
QFinalState* <xsl:apply-templates mode="stateid" select="." />; |
| 203 |
</xsl:for-each> |
| 204 |
<xsl:for-each select="//s:history"> |
| 205 |
<xsl:call-template name="comment" /> |
| 206 |
QHistoryState* <xsl:apply-templates mode="stateid" select="." />; |
| 207 |
</xsl:for-each> |
| 208 |
<xsl:for-each select="//s:transition[string(@cond) != '']"> |
| 209 |
<xsl:call-template name="comment" /> |
| 210 |
inline bool testCondition_<xsl:value-of select="generate-id()" />() |
| 211 |
{ |
| 212 |
return <xsl:if test="string(@cond)=''">true</xsl:if><xsl:value-of select="@cond"/>; |
| 213 |
} |
| 214 |
</xsl:for-each> |
| 215 |
<xsl:for-each select="//s:datamodel/s:data"> |
| 216 |
<xsl:call-template name="comment" /> |
| 217 |
<xsl:text> </xsl:text><xsl:value-of select="@Qt:type" /> get_<xsl:value-of select="@id" />() const |
| 218 |
{ |
| 219 |
return _data.<xsl:value-of select="@id" />; |
| 220 |
} |
| 221 |
</xsl:for-each> |
| 222 |
<xsl:if test="count(//s:datamodel/s:data) != 0"><![CDATA[ |
| 223 |
protected: |
| 224 |
struct { |
| 225 |
]]><xsl:for-each select="//s:datamodel/s:data"> |
| 226 |
<xsl:call-template name="comment" /> |
| 227 |
<xsl:text> </xsl:text><xsl:value-of select="@Qt:type" /><xsl:text> </xsl:text><xsl:value-of select="@id" />; |
| 228 |
</xsl:for-each> |
| 229 |
} _data; |
| 230 |
</xsl:if> |
| 231 |
struct { |
| 232 |
QString name; |
| 233 |
QVariantList data; |
| 234 |
} _event; |
| 235 |
QString _name; |
| 236 |
<xsl:if test="(count(//s:datamodel/s:data)+count(/s:scxml/s:script))!=0"> |
| 237 |
public Q_SLOTS: |
| 238 |
</xsl:if> |
| 239 |
<xsl:for-each select="//s:datamodel/s:data"> |
| 240 |
<xsl:call-template name="comment" /> |
| 241 |
void set_<xsl:value-of select="@id" />(<xsl:value-of select="@Qt:type" /> const & value) |
| 242 |
{ |
| 243 |
_data.<xsl:value-of select="@id" /> = value; |
| 244 |
emit <xsl:value-of select="@id" />_changed(value); |
| 245 |
} |
| 246 |
</xsl:for-each> |
| 247 |
private Q_SLOTS: |
| 248 |
#ifndef QT_NO_PROPERTIES |
| 249 |
void assignProperties() |
| 250 |
{ |
| 251 |
<xsl:for-each select="//Qt:property"> |
| 252 |
<xsl:call-template name="comment" /> |
| 253 |
<xsl:text> </xsl:text><xsl:apply-templates mode="stateid" select=".." />->assignProperty(<xsl:value-of |
| 254 |
select="@object" />,"<xsl:value-of select="@property" />",QVariant(<xsl:value-of select="@value" />)); |
| 255 |
</xsl:for-each> |
| 256 |
#endif |
| 257 |
} |
| 258 |
<xsl:for-each select="//s:transition|//s:onentry|//s:onexit"><xsl:if test="count(*) != 0"> |
| 259 |
<xsl:for-each select="..|."><xsl:call-template name="comment" /></xsl:for-each> |
| 260 |
void exec_<xsl:value-of select="generate-id()" />() |
| 261 |
{ |
| 262 |
<xsl:apply-templates mode="execContext" /> |
| 263 |
} |
| 264 |
</xsl:if></xsl:for-each> |
| 265 |
Q_SIGNALS:<xsl:for-each select="distinct-values(//node()[not (starts-with(@event,'done.state.') or @event='*' or contains(@event,':'))]/@event)"> |
| 266 |
void event_<xsl:value-of select="replace(string(),'\.','__')" /><xsl:if test="not(contains(string(),')'))">()</xsl:if>;</xsl:for-each> |
| 267 |
<xsl:for-each select="//s:datamodel/s:data"> |
| 268 |
<xsl:call-template name="comment" /> |
| 269 |
void <xsl:value-of select="@id" />_changed(<xsl:value-of select="@Qt:type" /> const &); |
| 270 |
</xsl:for-each> |
| 271 |
<xsl:text><![CDATA[ |
| 272 |
protected: |
| 273 |
virtual void beginSelectTransitions(QEvent *event) |
| 274 |
{ |
| 275 |
if (event && !event->type() == QEvent::None) { |
| 276 |
switch (event->type()) { |
| 277 |
case QEvent::StateMachineSignal: { |
| 278 |
QStateMachine::SignalEvent* e = (QStateMachine::SignalEvent*)event; |
| 279 |
_event.data = e->arguments(); |
| 280 |
_event.name = e->sender()->metaObject()->method(e->signalIndex()).signature(); |
| 281 |
if (e->sender() == this) |
| 282 |
_event.name = _event.name.mid(6); |
| 283 |
} break; |
| 284 |
default: |
| 285 |
break; |
| 286 |
} |
| 287 |
} else { |
| 288 |
_event.name = ""; |
| 289 |
_event.data.clear(); |
| 290 |
} |
| 291 |
]]> |
| 292 |
assignProperties(); |
| 293 |
} |
| 294 |
</xsl:text> |
| 295 |
<xsl:if test="count(//s:send[string(@target)!='internal']) != 0"> |
| 296 |
private: |
| 297 |
<xsl:text><![CDATA[QHash<QString,QPointer<SCC_EventSender> >]]></xsl:text> _eventSenders; |
| 298 |
</xsl:if> |
| 299 |
protected: |
| 300 |
public: |
| 301 |
void setupStateMachine() |
| 302 |
{ |
| 303 |
_name = "<xsl:call-template name="smname" />"; |
| 304 |
setObjectName(_name); |
| 305 |
<xsl:for-each select="//s:state|//s:parallel|//s:final|//s:history|//s:initial"> |
| 306 |
<xsl:call-template name="comment" /> |
| 307 |
<xsl:text> </xsl:text><xsl:apply-templates mode="stateid" select="." /> = new <xsl:choose> |
| 308 |
<xsl:when test="name()='final'">QFinalState</xsl:when> |
| 309 |
<xsl:when test="name()='history'">QHistoryState</xsl:when> |
| 310 |
<xsl:otherwise>QState</xsl:otherwise> |
| 311 |
</xsl:choose>(<xsl:apply-templates mode="stateid" select=".." />); |
| 312 |
<xsl:if test="string(@id)!=''"><xsl:apply-templates mode="stateid" select="." />->setObjectName("<xsl:value-of select="@id" />");</xsl:if> |
| 313 |
<xsl:if |
| 314 |
test="name()='initial' or @id=../@initial"> |
| 315 |
<xsl:apply-templates mode="stateid" select=".." />->setInitialState(<xsl:apply-templates mode="stateid" select="." />); |
| 316 |
</xsl:if> |
| 317 |
<xsl:if test="name()='parallel'"> |
| 318 |
<xsl:apply-templates mode="stateid" select="." />->setChildMode(ParallelStates); |
| 319 |
</xsl:if> |
| 320 |
<xsl:if test="name()='history'"> |
| 321 |
<xsl:apply-templates mode="stateid" select="." />->setHistoryType(QHistoryState::<xsl:choose> |
| 322 |
<xsl:when test="@type='deep'">Deep</xsl:when> |
| 323 |
<xsl:otherwise>Shallow</xsl:otherwise> |
| 324 |
</xsl:choose>History); |
| 325 |
</xsl:if> |
| 326 |
</xsl:for-each> |
| 327 |
QAbstractTransition* transition;<xsl:for-each select="//s:transition[../name()!='history']"> |
| 328 |
<xsl:call-template name="comment" /> |
| 329 |
transition = new <xsl:choose> |
| 330 |
<xsl:when test="@event='*' or string(@cond)!=''">Transition_<xsl:value-of |
| 331 |
select="generate-id()" />(</xsl:when> |
| 332 |
<xsl:when test="starts-with(@event,'q-event:')">QEventTransition(<xsl:value-of |
| 333 |
select="substring-after(@event,'q-event:')" />,</xsl:when> |
| 334 |
<xsl:when test="starts-with(@event,'done.state.')">QSignalTransition(state_<xsl:value-of |
| 335 |
select="substring-after(@event,'done.state.')" />,SIGNAL(finished()),</xsl:when> |
| 336 |
<xsl:when test="string(@event)!=''">QSignalTransition(this,SIGNAL(event_<xsl:value-of select="replace(@event,'\.','__')" /><xsl:if test="not(ends-with(@event,')'))">()</xsl:if>),</xsl:when> |
| 337 |
<xsl:otherwise>SCC_UnconditionalTransition(</xsl:otherwise></xsl:choose><xsl:apply-templates mode="stateid" select=".." />);<xsl:if test="count(*) != 0"> |
| 338 |
connect(transition,SIGNAL(triggered()),this,SLOT(exec_<xsl:value-of select="generate-id()" />()));</xsl:if> |
| 339 |
<xsl:if test="string(@Qt:animation) != ''"> |
| 340 |
transition->addAnimation(<xsl:value-of select="@Qt:animation" />);</xsl:if><xsl:if |
| 341 |
test="string(@target) != ''"></xsl:if> |
| 342 |
<xsl:choose> |
| 343 |
<xsl:when test="string(@target)=''" /> |
| 344 |
<xsl:when test="count(tokenize(@target,'\s+'))=1"> |
| 345 |
transition->setTargetState(state_<xsl:value-of select="@target" />);</xsl:when> |
| 346 |
<xsl:otherwise>(*transition).setTargetStates(QList<QAbstractState*>()<xsl:for-each |
| 347 |
select="tokenize(@target,'\s+')"> << state_<xsl:value-of select="." /></xsl:for-each>);</xsl:otherwise> |
| 348 |
</xsl:choose> |
| 349 |
</xsl:for-each> |
| 350 |
<xsl:for-each select="//s:history/s:transition"> |
| 351 |
<xsl:apply-templates mode="stateid" select=".." />->setDefaultState(state_<xsl:value-of select="@target" />); |
| 352 |
</xsl:for-each> |
| 353 |
<xsl:for-each select="//s:onentry|//s:onexit"><xsl:if test="count(*) != 0"> |
| 354 |
connect(<xsl:apply-templates mode="stateid" select=".." />, SIGNAL(<xsl:choose> |
| 355 |
<xsl:when test="name()='onentry'">entered</xsl:when> |
| 356 |
<xsl:when test="name()='onexit'">exited</xsl:when> |
| 357 |
</xsl:choose>()),this,SLOT(exec_<xsl:value-of select="generate-id()" />()));</xsl:if></xsl:for-each> |
| 358 |
<xsl:value-of select="/s:scxml/s:script/text()" /> |
| 359 |
} |
| 360 |
}; |
| 361 |
<xsl:for-each select="//s:transition[@event='*' or string(@cond) != '']"> |
| 362 |
<xsl:call-template name="comment" /> |
| 363 |
bool Transition_<xsl:value-of select="generate-id()" />::eventTest(QEvent* e) |
| 364 |
{ |
| 365 |
return <xsl:choose><xsl:when test="@event!='*'">Q<xsl:if test="string(@event) != ''">Signal</xsl:if>Transition::eventTest(e) |
| 366 |
</xsl:when><xsl:otherwise>(*e).type() != QEvent::None</xsl:otherwise></xsl:choose><xsl:if test="string(@cond)!=''">&& stateMachine->testCondition_<xsl:value-of |
| 367 |
select="generate-id()" />()</xsl:if>; |
| 368 |
} |
| 369 |
</xsl:for-each> |
| 370 |
#endif |
| 371 |
</xsl:template> |
| 372 |
|
| 373 |
</xsl:stylesheet> |