XSLT Rekursions-Problem

PatPat

Grünschnabel
Hallo,

Ich möchte mittels XSLT eine SVG-Datei erzeugen.

Aus einem Set von "wire"-Objekten (s. u.) soll ein SVG "path"-Objekt werden.

HTML:
<wire x1="48.716000" y1="205.882700" x2="48.716000" y2="188.072000">

Das gewünschte Polygon kann dabei aus mehreren Teilpolygonen zusammengesetzt sein (gefüllte Fläche mit "Löchern").

Wenn Punkt 2 eines wires (x2,y2) mit Punkt 1 des ersten wires übereinstimmt soll das Polygon geschlossen werden und mit dem folgenden wire ein neues (Unter-)Polygon begonnen werden.

Zur Lösung könnte man
  1. die Anfangskoordinaten (x1,y1) eines Teilpolygons in einer Variablen speichern, bei Übereinstimmung das Polygon schließen und die neuen Anfangskoordinaten in der Variablen speichern (in XSLT nicht möglich, da sich der Inhalt einer variablen nicht verändern lässt)
  2. die Anfangskoordinaten (x1,y1) eines Teilpolygons in einer Variablen speichern, bei Übereinstimmung das Polygon schließen und mit den verbleibenden Knoten dieselbe Funktion rekursiv durchlaufen, bis alle Teilpolygone geplottet sind.

Die folgenden templates setzen Lösungsansatz 2 um, allerdings mit dem Problem, dass die restlichen wires, die an die Rekursion geschickt wurden, natürlich im aufrufenden template nochmal verarbeitet werden und so zu ungewünschten Ergebnissen führen.

Wie kann ich dieses Problem lösen? Gibt es eine Möglichkeit, eine for-each-Schleife vorzeitig zu verlassen (eine Art break...)?

HTML:
<xsl:template match="polygon">
	<xsl:element name="path">
		<xsl:attribute name="d">
			<xsl:call-template name="draw-polygon">
				<xsl:with-param name="wire" select="contours/wire" />
			</xsl:call-template>
		</xsl:attribute>
	</xsl:element>
</xsl:template>

<xsl:template name="draw-polygon">
	<xsl:param name="wire" />
	<xsl:variable name="xAnfang" select="$wire[1]/@x1" />
	<xsl:variable name="yAnfang" select="$wire[1]/@y1" />	
	<xsl:for-each select="$wire">
		<xsl:if test="position() = 1">M <xsl:value-of select="@x1" />,-<xsl:value-of select="@y1" /></xsl:if>
		<xsl:if test="@x2 = $xAnfang and @y2 = $yAnfang">
			<xsl:text> Z </xsl:text>
			<xsl:call-template name="draw-polygon">
				<xsl:with-param name="wire" select="following-sibling::wire" />
			</xsl:call-template>
		</xsl:if>
		<xsl:text> L </xsl:text><xsl:value-of select="@x2" />,-<xsl:value-of select="@y2" />
	</xsl:for-each>
</xsl:template>

Vielen Dank für eure Hilfe
Patrick
 

Neue Beiträge

Zurück