Hi,
ok, funktioniert jetzt mit:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data [
<!ELEMENT data (events,participants)>
<!ELEMENT events (event)+>
<!ELEMENT event EMPTY>
<!ATTLIST event
id ID #REQUIRED
name CDATA #REQUIRED >
<!ELEMENT participant (participant)+>
<!ELEMENT participant EMPTY>
<!ATTLIST participant
name CDATA #REQUIRED
events IDREFS #REQUIRED >
]>
<data>
<events>
<event id="e01" name="bla"/>
<event id="e02" name="blubb"/>
<event id="e03" name="laber"/>
</events>
<participants>
<participant events="e01 e03" name="Alpha"/>
<participant events="e02" name="Bravo"/>
<participant events="e02 e03" name="Charlie"/>
</participants>
</data>
und diesem XSL-Ausschnitt:
<xsl:template match="participant" mode="byparticipant">
<h3><xsl:value-of select="@name"/></h3>
<xsl:apply-templates select="id(@events)" mode="byparticipant"/>
</xsl:template>
<xsl:template match="event" mode="byparticipant">
<xsl:if test="position() > 1">, </xsl:if>
<xsl:value-of select="@name"/>
</xsl:template>
Damit krieg ich jetzt zu jedem participant alle events, bei denen er dabei war.
An anderer Stelle will ich aber die Auflistung genau andersrum:
zu jedem Event die Liste aller participants.
Klar, ich könnte jetzt jedem participant ne id verpassen und im event wieder ein IDREFS-Attribut und das ganze symmetrisch aufbauen.
Aber: das erzeugt Redundanz - weil die Information, welche participants bei welchen events waren, steckt ja schon im XML drin.
Redundanz will ich vermeiden, denn das ist ein erhöhter Pflegeaufwand, und das ganze wird fehleranfälliger - wenn z.B. bei einem participant zwar ein event eingetragen wird, der participant aber nicht beim event eingetragen wird.
Gibt es eine Umkehrfunktion zu id()?
Also eine Funktion, die alle Elemente liefert, die in einem per IDREFS deklarierten Attribut eine gegebene ID haben?
Ich hab nichts gefunden, weder in XSL noch in XPath. Hab ich was übersehen?
Im Moment nutze ich wieder den contains-"Hack" - aber der funktioniert ja nur, wenn keine ID in einer anderen ID enthalten ist (also bei i1 und i11 nicht):
<xsl:template match="event" mode="byevent">
<h3><xsl:value-of select="@name"/></h3>
<ul>
<xsl:variable name="eventid" select="@id"/>
<xsl:apply-templates select="//participants/participant[contains(@events, $eventid)]" mode="byevent"/>
</ul>
</xsl:template>
<xsl:template match="participant" mode="byevent">
<li><xsl:value-of select="@name"/></li>
</xsl:template>
Gibt es eine _sauberere_ Lösung dafür? Also eine, die mit beliebigen id-Werten funktioniert?
cu,
Andreas
MudGuard? Siehe http://www.Mud-Guard.de/
Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.