I am trying to find the minimum and maximum values for the X and Y values
within the start|end elements of all the <Line>s in the XML file (ie. minX,
minY, maxX, maxY). Does anyone have a simple/elegant solution or any
suggestions?
Thankyou
Adrian
<Parcels>
<Parcel name="801" area="554.065">
<CoordGeom>
<Line>
<Start>33505.95684580 31533.46501647</Start>
<End>33516.39685788 31545.58962565</End>
</Line>
<Line>
<Start>33516.39685788 31545.58962565</Start>
<End>33542.33349683 31523.25663165</End>
</Line>
...
</CoordGeom>
</Parcel>
<Parcel name="802" area="529.463">
...
</Parcel>
...
</Parcels>
Try this program: (requires MSXML though, because of the msxsl:node-set
function)
<?xml version="1.0"?>
<t:transform version="1.0"
xmlns:t="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<t:output encoding="UTF-8" method="text" />
<t:template match="/">
<t:variable name="res">
<t:call-template name="findMax">
<t:with-param name="lines" select="Parcels/Parcel/CoordGeom/Line" />
<t:with-param name="minX" select="100000000" />
<t:with-param name="maxX" select="-100000000" />
<t:with-param name="minY" select="100000000" />
<t:with-param name="maxY" select="-100000000" />
</t:call-template>
</t:variable>
MinX = <t:value-of select="msxsl:node-set($res)/minX" />
MaxX = <t:value-of select="msxsl:node-set($res)/maxX" />
MinY = <t:value-of select="msxsl:node-set($res)/minY" />
MaxY = <t:value-of select="msxsl:node-set($res)/maxY" />
</t:template>
<t:template name="findMax">
<t:param name="lines" />
<t:param name="minX" />
<t:param name="maxX" />
<t:param name="minY" />
<t:param name="maxY" />
<t:choose>
<t:when test="count($lines) = 0">
<minX><t:value-of select="$minX" /></minX>
<maxX><t:value-of select="$maxX" /></maxX>
<minY><t:value-of select="$minY" /></minY>
<maxY><t:value-of select="$maxY" /></maxY>
</t:when>
<t:otherwise>
<t:variable name="car" select="msxsl:node-set($lines)[1]" />
<t:variable name="cdr" select="msxsl:node-set($lines)[position() != 1]"
/>
<t:variable name="X1" select="substring-before($car/Start, ' ')" />
<t:variable name="Y1" select="substring-after($car/Start, ' ')" />
<t:variable name="X2" select="substring-before($car/End, ' ')" />
<t:variable name="Y2" select="substring-after($car/End, ' ')" />
<t:variable name="localMinX">
<t:call-template name="min">
<t:with-param name="t1" select="$X1" />
<t:with-param name="t2" select="$X2" />
</t:call-template>
</t:variable>
<t:variable name="localMaxX">
<t:call-template name="max">
<t:with-param name="t1" select="$X1" />
<t:with-param name="t2" select="$X2" />
</t:call-template>
</t:variable>
<t:variable name="newMinX">
<t:call-template name="min">
<t:with-param name="t1" select="$minX" />
<t:with-param name="t2" select="$localMinX" />
</t:call-template>
</t:variable>
<t:variable name="newMaxX">
<t:call-template name="max">
<t:with-param name="t1" select="$maxX" />
<t:with-param name="t2" select="$localMaxX" />
</t:call-template>
</t:variable>
<t:variable name="localMinY">
<t:call-template name="min">
<t:with-param name="t1" select="$Y1" />
<t:with-param name="t2" select="$Y2" />
</t:call-template>
</t:variable>
<t:variable name="localMaxY">
<t:call-template name="max">
<t:with-param name="t1" select="$Y1" />
<t:with-param name="t2" select="$Y2" />
</t:call-template>
</t:variable>
<t:variable name="newMinY">
<t:call-template name="min">
<t:with-param name="t1" select="$minY" />
<t:with-param name="t2" select="$localMinY" />
</t:call-template>
</t:variable>
<t:variable name="newMaxY">
<t:call-template name="max">
<t:with-param name="t1" select="$maxY" />
<t:with-param name="t2" select="$localMaxY" />
</t:call-template>
</t:variable>
<t:variable name="cdrResult">
<t:call-template name="findMax">
<t:with-param name="lines" select="$cdr" />
<t:with-param name="minX" select="$newMinX" />
<t:with-param name="maxX" select="$newMaxX" />
<t:with-param name="minY" select="$newMinY" />
<t:with-param name="maxY" select="$newMaxY" />
</t:call-template>
</t:variable>
<minX><t:value-of select="msxsl:node-set($cdrResult)/minX" /></minX>
<maxX><t:value-of select="msxsl:node-set($cdrResult)/maxX" /></maxX>
<minY><t:value-of select="msxsl:node-set($cdrResult)/minY" /></minY>
<maxY><t:value-of select="msxsl:node-set($cdrResult)/maxY" /></maxY>
</t:otherwise>
</t:choose>
</t:template>
<t:template name="min">
<t:param name="t1" />
<t:param name="t2" />
<t:choose>
<t:when test="$t1 < $t2">
<t:value-of select="$t1" />
</t:when>
<t:otherwise>
<t:value-of select="$t2" />
</t:otherwise>
</t:choose>
</t:template>
<t:template name="max">
<t:param name="t1" />
<t:param name="t2" />
<t:choose>
<t:when test="$t1 > $t2">
<t:value-of select="$t1" />
</t:when>
<t:otherwise>
<t:value-of select="$t2" />
</t:otherwise>
</t:choose>
</t:template>
</t:transform>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list