 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

March 15th, 2009, 03:08 PM
|
|
Authorized User
|
|
Join Date: Mar 2009
Posts: 50
Thanks: 7
Thanked 0 Times in 0 Posts
|
|
I've just figured out that those y coordinate values of 150 and 550 are simply the layerTopDepth and layerBaseDepth values. The calculation in those doesn't seem to have taken place. Strange though because the other values seem active when I remove layerTopDepth from the equation.
I am severely confused!
|
|

March 15th, 2009, 03:39 PM
|
|
Authorized User
|
|
Join Date: Mar 2009
Posts: 50
Thanks: 7
Thanked 0 Times in 0 Posts
|
|
almost..almost there!
Ok so the problem I had before was that altitudeGL was accidentally declared with some of the constant variables (like name of layer and layer id etc). It's now set to vary like the others.
So now I have all of the correct numbers..except for on the return journey of the path, my y coordinates are ordered incorrectly! (And that's it.) I can't see why they aren't ordered as I asked them to...
Code:
<xsl:for-each select="$groundLayers">
<path...>
<xsl:attribute name="d">
<xsl:for-each select=".">
<xsl:sort select="xs:double(distanceGL)" order="descending"/>
<xsl:text>M</xsl:text>
<xsl:value-of select="$distance - distanceGL[1]"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$height - altitudeGL[1] + layerTopDepth[1]"/>
</xsl:for-each>
<xsl:text> L </xsl:text>
<xsl:for-each select="distanceGL">
<xsl:sort select="xs:double(.)" order="descending"/>
<xsl:variable name="posa" select="position()"/>
<xsl:value-of
select="concat($distance - ., ' ', (($height - parent::layers/child::altitudeGL[$posa]) + parent::layers/child::layerTopDepth[$posa]))"/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>, </xsl:text>
<xsl:for-each select="distanceGL">
<xsl:sort select="xs:double(.)" order="ascending"/>
<xsl:variable name="posb" select="position()"/>
<xsl:value-of
select="concat($distance - ., ' ', (($height - parent::layers/child::altitudeGL[$posb]) + parent::layers/child::layerBaseDepth[$posb]))"/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>z</xsl:text>
</xsl:attribute>
</path>
Here is a path we are aiming for:
d="M0 400 L 0 400, 363 449, 363 449, 0 550z"
and this is what we now have:
d="M0 400 L 0 400, 363 449, 363 550, 0 449z"
Is there some sort of maybe 'reverse position()' command?
edit: my guess is that because distanceGL and altitudeGL have been split up, they have lost some kind of relationship needed for this? I would have thought though that the variable $pos would have fixed that? I'm sure you can probably see something I can't!
edit2: I just double checked everything and yes it does draw the top line of the path correctly. The problem is definitely just the y values on the return of the path (more specifically these are the values as a result of the calc including layerBaseDepth). I think some further sort or link is needed so that the values know to follow the same order as the x values.
Last edited by jamesdurham; March 15th, 2009 at 03:57 PM..
|
|

March 15th, 2009, 09:10 PM
|
|
Authorized User
|
|
Join Date: Mar 2009
Posts: 50
Thanks: 7
Thanked 0 Times in 0 Posts
|
|
I've spent hours trying out why the order for the y coordinates on the final path for-each are the wrong way round. They are ordered still by descending distanceGL whereas they should be by ascending distanceGL.
This is the offending section:
Code:
</xsl:for-each>
<xsl:text>, </xsl:text>
<xsl:for-each select="distanceGL">
<xsl:sort select="xs:double(.)" order="ascending"/>
<xsl:variable name="posb" select="position()"/>
<xsl:value-of
select="concat($distance - ., ' ', (($height - parent::layers/child::altitudeGL[$posb]) + parent::layers/child::layerBaseDepth[$posb]))"/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
The actual distanceGL numbers have been ordered correctly because the x coordinates are directly based on this fact and they turn out correct. This means that they are not affecting the altitudeGL and layerBaseDepth orders by use of that variable. If there another alternative for them to follow distanceGL's change of order?
This is all I need to finish the tricky bits..the rest is functionality etc after this (which I enjoy more and am better at!). Thanks
edit: I tried using select="reverse(position())" but that had no effect.
Last edited by jamesdurham; March 16th, 2009 at 08:21 AM..
|
|

March 16th, 2009, 08:58 AM
|
|
Authorized User
|
|
Join Date: Mar 2009
Posts: 50
Thanks: 7
Thanked 0 Times in 0 Posts
|
|
Hi Martin.
If you don't know what could be wrong here and need more information then please ask. If you don't think you can help with this bit then please let me know.
I couldn't have spotted all of these things so quickly, if at all, if it wasn't for your help! So thank you. I'd hate to have failed with this new xml structure on this last issue..it seems to me like it would be simple to fix with the right know-how! I hate not having more experience with this to draw on.
Cheers.
|
|

March 16th, 2009, 09:11 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Try to isolate the problem by making small but complete samples of the current input (which I think is an intermediate result of your complete stylesheet) and a small but complete stylesheet only focussing on that part that does not work as you want.
Then state which XSLT processor you use and show us the result you get and the result you want.
That way we should hopefully be able to find why things don't work as intended.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

March 16th, 2009, 09:21 AM
|
|
Authorized User
|
|
Join Date: Mar 2009
Posts: 50
Thanks: 7
Thanked 0 Times in 0 Posts
|
|
Ok thanks, I'll do that now.
edit: This may be tricky to get to work without depending on many other parts! I'll see what I can do, if not I may have to supply a very lengthy set of code in order for it to work on your end!
Last edited by jamesdurham; March 16th, 2009 at 09:35 AM..
|
|

March 16th, 2009, 10:03 AM
|
|
Authorized User
|
|
Join Date: Mar 2009
Posts: 50
Thanks: 7
Thanked 0 Times in 0 Posts
|
|
Here's the xml and xsl file for only the parts needed in order to draw the ground layer paths. It cannot be cut down any further I'm afraid without it losing function. So the code here can be saved and used by yourself on your machine. If you want it broken down more then I can provide it but it won't function on your end.
xml:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ErrorCheck.xsl"?>
<geo:slopeData xmlns:geo="www.dur.ac.uk/geo-engineering"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svg="http://www.w3.org/2000/svg" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:gml="http://www.opengis.com/gml/3.2"
xmlns:kml="http://earth.google.com/kml/2.0" xmlns:diggs="http://www.diggml.com">
<geo:case caseID="ID1">
<geo:slope>
<geo:toe>
<geo:location>
<gml:Point gml:id="slopeBase">
<gml:pos>316165 505658</gml:pos>
</gml:Point>
<geo:Height>-70</geo:Height>
</geo:location>
</geo:toe>
<geo:crest>
<geo:location>
<gml:Point gml:id="slopePeak">
<gml:pos>316865 504940</gml:pos>
</gml:Point>
<geo:Height>749</geo:Height>
</geo:location>
</geo:crest>
<geo:level2Points>
<geo:location coords="1" height="1">
<gml:Point gml:id="level2points">
<gml:pos>316570 505159</gml:pos>
</gml:Point>
<geo:Height>450</geo:Height>
</geo:location>
<geo:location coords="1" height="1">
<gml:Point gml:id="level2points">
<gml:pos>316065 505418</gml:pos>
</gml:Point>
<geo:Height>200</geo:Height>
</geo:location>
<geo:location coords="1">
<gml:Point gml:id="level2points">
<gml:pos>316850 505727</gml:pos>
</gml:Point>
<geo:Height>250</geo:Height>
</geo:location>
</geo:level2Points>
<geo:groundLayers>
<diggs:Hole diggs:id="1">
<diggs:location>
<gml:Point>
<gml:pos>316865 504940</gml:pos>
</gml:Point>
<geo:height>749</geo:height>
</diggs:location>
<diggs:layerSystems>
<diggs:LayerSystem>
<diggs:layers>
<diggs:Layer>
<diggs:id>1</diggs:id>
<diggs:primaryName>Layer1</diggs:primaryName>
<diggs:top>
<gml:pos>0</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>400</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Medium dense red brown clayey very sandy
angular to rounded fine to coarse quartz, igneous material,
sandstone and concrete GRAVEL.</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
<diggs:Layer>
<diggs:id>2</diggs:id>
<diggs:primaryName>Layer2</diggs:primaryName>
<diggs:top>
<gml:pos>400</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>550</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Very weak green grey MUDSTONE. Fractures are closely spaced,
horizontal, clean and smooth. (Eldersfield Mudstone
Formation)</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
<diggs:Layer>
<diggs:id>3</diggs:id>
<diggs:primaryName>Layer3</diggs:primaryName>
<diggs:top>
<gml:pos>550</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>750</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Medium dense to dense red brown slightly clayey SAND and
GRAVEL with rare cobbles. Gravel is subangular to rounded fine
to coarse of quartz, igneous material and sandstone. Cobbles are
subangular to rounded of quartz and igneous material. (River
Terrace Deposits)</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
</diggs:layers>
</diggs:LayerSystem>
</diggs:layerSystems>
</diggs:Hole>
<diggs:Hole diggs:id="2">
<diggs:location>
<gml:Point>
<gml:pos>316570 505159</gml:pos>
</gml:Point>
<geo:height>450</geo:height>
</diggs:location>
<diggs:layerSystems>
<diggs:LayerSystem>
<diggs:layers>
<diggs:Layer>
<diggs:id>1</diggs:id>
<diggs:primaryName>Layer1</diggs:primaryName>
<diggs:top>
<gml:pos>0</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>150</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Medium dense red brown clayey very sandy
angular to rounded fine to coarse quartz, igneous material,
sandstone and concrete GRAVEL.</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
<diggs:Layer>
<diggs:id>2</diggs:id>
<diggs:primaryName>Layer2</diggs:primaryName>
<diggs:top>
<gml:pos>150</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>150</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Very weak green grey MUDSTONE. Fractures are closely spaced,
horizontal, clean and smooth. (Eldersfield Mudstone
Formation)</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
<diggs:Layer>
<diggs:id>3</diggs:id>
<diggs:primaryName>Layer3</diggs:primaryName>
<diggs:top>
<gml:pos>150</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>470</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Medium dense to dense red brown slightly clayey SAND and
GRAVEL with rare cobbles. Gravel is subangular to rounded fine
to coarse of quartz, igneous material and sandstone. Cobbles are
subangular to rounded of quartz and igneous material. (River
Terrace Deposits)</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
</diggs:layers>
</diggs:LayerSystem>
</diggs:layerSystems>
</diggs:Hole>
<diggs:Hole diggs:id="3">
<diggs:location>
<gml:Point>
<gml:pos>316850 505727</gml:pos>
</gml:Point>
<geo:height>250</geo:height>
</diggs:location>
<diggs:layerSystems>
<diggs:LayerSystem>
<diggs:layers>
<diggs:Layer>
<diggs:id>1</diggs:id>
<diggs:primaryName>Layer1</diggs:primaryName>
<diggs:top>
<gml:pos>0</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>100</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Medium dense red brown clayey very sandy
angular to rounded fine to coarse quartz, igneous material,
sandstone and concrete GRAVEL.</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
<diggs:Layer>
<diggs:id>3</diggs:id>
<diggs:primaryName>Layer3</diggs:primaryName>
<diggs:top>
<gml:pos>100</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>270</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Medium dense to dense red brown slightly clayey SAND and
GRAVEL with rare cobbles. Gravel is subangular to rounded fine
to coarse of quartz, igneous material and sandstone. Cobbles are
subangular to rounded of quartz and igneous material. (River
Terrace Deposits)</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
</diggs:layers>
</diggs:LayerSystem>
</diggs:layerSystems>
</diggs:Hole>
<diggs:Hole diggs:id="4">
<diggs:location>
<gml:Point>
<gml:pos>316065 505418</gml:pos>
</gml:Point>
<geo:height>200</geo:height>
</diggs:location>
<diggs:layerSystems>
<diggs:LayerSystem>
<diggs:layers>
<diggs:Layer>
<diggs:id>1</diggs:id>
<diggs:primaryName>Layer1</diggs:primaryName>
<diggs:top>
<gml:pos>0</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>50</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Medium dense red brown clayey very sandy
angular to rounded fine to coarse quartz, igneous material,
sandstone and concrete GRAVEL.</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
<diggs:Layer>
<diggs:id>3</diggs:id>
<diggs:primaryName>Layer3</diggs:primaryName>
<diggs:top>
<gml:pos>50</gml:pos>
</diggs:top>
<diggs:base>
<gml:pos>220</gml:pos>
</diggs:base>
<diggs:descriptions>
<diggs:Description>
<diggs:value>Medium dense to dense red brown slightly clayey SAND and
GRAVEL with rare cobbles. Gravel is subangular to rounded fine
to coarse of quartz, igneous material and sandstone. Cobbles are
subangular to rounded of quartz and igneous material. (River
Terrace Deposits)</diggs:value>
</diggs:Description>
</diggs:descriptions>
</diggs:Layer>
</diggs:layers>
</diggs:LayerSystem>
</diggs:layerSystems>
</diggs:Hole>
</geo:groundLayers>
</geo:slope>
</geo:case>
</geo:slopeData>
xsl:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:math="http://exslt.org/math"
xmlns:geo="www.dur.ac.uk/geo-engineering" xmlns:gml="http://www.opengis.com/gml/3.2"
exclude-result-prefixes="xs math geo gml diggs" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:diggs="http://www.diggml.com">
<!-- Used to define that all elements' white space to be removed -->
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" doctype-public="-//W3C//DTD SVG 1.1//EN"
doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"/>
<!-- Leaves CDATA sections in output -->
<xsl:output cdata-section-elements="script style"/>
<xsl:template match="/">
<xsl:apply-templates mode="svg"/>
</xsl:template>
<xsl:template match="geo:slopeData" mode="svg">
<svg width="900px" height="600px" version="1.1" viewBox="0 0 1700 1100"
preserveAspectRatio="xMinYMin">
<xsl:apply-templates select="geo:case" mode="svg"/>
</svg>
</xsl:template>
<xsl:template match="geo:case" mode="svg">
<!-- Level 1 Variables -->
<xsl:variable name="toe" as="xs:integer+" select="geo:point(geo:slope/geo:toe/geo:location)"/>
<xsl:variable name="crest" as="xs:integer+"
select="geo:point(geo:slope/geo:crest/geo:location)"/>
<xsl:variable name="diff" as="xs:integer+" select="$toe[1] - $crest[1], $toe[2] - $crest[2]"/>
<xsl:variable name="distance" as="xs:integer"
select="xs:integer(round(math:sqrt($diff[1] * $diff[1] + $diff[2] * $diff[2])))"/>
<xsl:variable name="altitude" as="xs:integer+" select="(//geo:Height)"/>
<xsl:variable name="height" as="xs:integer">
<xsl:choose>
<xsl:when test="$altitude[1] < 0">
<xsl:value-of select="$altitude[2] - $altitude[1]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$altitude[2] - $altitude[1]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="angle" as="xs:integer"
select="xs:integer(round(57.2957795*(math:atan2($height, $distance))))"/>
<!-- Level 2 Variables -->
<xsl:variable name="m1" as="xs:decimal" select="$diff[2] div $diff[1]"/>
<xsl:variable name="c1" as="xs:decimal" select="$toe[2] - (($m1)*$toe[1])"/>
<!-- y1=(m1*x) + c -->
<xsl:variable name="m2" as="xs:decimal" select="-1 div $m1"/>
<xsl:variable name="mdiff" as="xs:decimal" select="$m2 - $m1"/>
<!-- Ground layer variables -->
<xsl:variable name="groundLayers" as="element(layers)+">
<xsl:for-each-group
select="geo:slope/geo:groundLayers/diggs:Hole/diggs:layerSystems/diggs:LayerSystem/diggs:layers/diggs:Layer"
group-by="diggs:id">
<xsl:sort select="current-grouping-key()"/>
<layers xmlns="">
<xsl:variable name="layerName" select="diggs:primaryName"/>
<xsl:variable name="layerId" select="diggs:id" as="xs:integer"/>
<xsl:variable name="layerDescription"
select="diggs:descriptions/diggs:Description/diggs:value"/>
<layerId>
<xsl:value-of select="$layerId"/>
</layerId>
<layerDescription>
<xsl:value-of select="$layerDescription"/>
</layerDescription>
<layerName>
<xsl:value-of select="$layerName"/>
</layerName>
<xsl:for-each select="current-group()">
<xsl:variable name="layerTopDepth" select="diggs:top/gml:pos"/>
<xsl:variable name="layerBaseDepth" select="diggs:base/gml:pos"/>
<xsl:variable name="groundLayer" as="xs:integer+"
select="parent::diggs:layers/parent::diggs:LayerSystem/parent::diggs:layerSystems/parent::diggs:Hole/geo:point3(.)"/>
<xsl:variable name="coordinateX1" as="xs:integer" select="$groundLayer[1]"/>
<xsl:variable name="coordinateY1" as="xs:integer" select="$groundLayer[2]"/>
<xsl:variable name="c2" as="xs:decimal"
select="$groundLayer[2] - (($m2)*$groundLayer[1])"/>
<xsl:variable name="cdiff" as="xs:decimal" select="$c1 - $c2"/>
<xsl:variable name="xi" as="xs:decimal" select="$cdiff div $mdiff"/>
<xsl:variable name="yi" as="xs:decimal" select="($m2*$xi)+$c2"/>
<xsl:variable name="xdiff" as="xs:decimal" select="$toe[1] - $xi"/>
<xsl:variable name="ydiff" as="xs:decimal" select="$toe[2] - $yi"/>
<xsl:variable name="distanceGL"
select="xs:integer(round(math:sqrt($ydiff * $ydiff + $xdiff * $xdiff)))"
as="xs:decimal"/>
<xsl:variable name="heightGL" as="xs:integer"
select="parent::diggs:layers/parent::diggs:LayerSystem/parent::diggs:layerSystems/preceding-sibling::diggs:location/geo:height"/>
<xsl:variable name="altitudeGL" as="xs:integer">
<xsl:choose>
<xsl:when test="$altitude[1] < 0">
<xsl:value-of select="$heightGL - $altitude[1]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$heightGL - $altitude[1]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<heightGL>
<xsl:value-of select="$heightGL"/>
</heightGL>
<distanceGL>
<xsl:value-of select="$distanceGL"/>
</distanceGL>
<altitudeGL>
<xsl:value-of select="$altitudeGL"/>
</altitudeGL>
<coordinateX1>
<xsl:value-of select="$coordinateX1"/>
</coordinateX1>
<coordinateY1>
<xsl:value-of select="$coordinateY1"/>
</coordinateY1>
<layerTopDepth>
<xsl:value-of select="$layerTopDepth"/>
</layerTopDepth>
<layerBaseDepth>
<xsl:value-of select="$layerBaseDepth"/>
</layerBaseDepth>
</xsl:for-each>
</layers>
</xsl:for-each-group>
</xsl:variable>
<!-- Diagram for ground layers -->
<g transform="translate(50,150)">
<g id="gLayers">
<xsl:for-each select="$groundLayers">
<xsl:variable name="layerId" select="layerId"/>
<xsl:variable name="layerDescription" select="layerDescription"/>
<xsl:variable name="layerName" select="layerName"/>
<path id="groundLayer{$layerId}" stroke-width="2" stroke="black" fill="none">
<xsl:attribute name="d">
<xsl:for-each select=".">
<xsl:sort select="xs:double(distanceGL)" order="descending"/>
<xsl:text>M</xsl:text>
<xsl:value-of select="$distance - distanceGL[1]"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$height - altitudeGL[1] + layerTopDepth[1]"/>
</xsl:for-each>
<xsl:text> L </xsl:text>
<xsl:for-each select="distanceGL">
<xsl:sort select="xs:double(.)" order="descending"/>
<xsl:variable name="posa" select="position()"/>
<xsl:value-of
select="concat($distance - ., ' ', (($height - parent::layers/child::altitudeGL[$posa]) + parent::layers/child::layerTopDepth[$posa]))"/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>, </xsl:text>
<xsl:for-each select="distanceGL">
<xsl:sort select="xs:double(.)" order="ascending"/>
<xsl:variable name="posb" select="position()"/>
<xsl:value-of
select="concat($distance - ., ' ', (($height - parent::layers/child::altitudeGL[$posb]) + parent::layers/child::layerBaseDepth[$posb]))"/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>z</xsl:text>
</xsl:attribute>
</path>
</xsl:for-each>
</g>
</g>
</xsl:template>
<!-- Level 1 Function -->
<xsl:function name="geo:point" as="xs:integer+">
<xsl:param name="location" as="element(geo:location)"/>
<xsl:variable name="point" as="xs:string" select="$location/gml:Point/gml:pos"/>
<xsl:sequence select="xs:integer(substring-before($point, ' '))"/>
<xsl:sequence select="xs:integer(substring-after($point, ' '))"/>
</xsl:function>
<!-- Ground Layer Function -->
<xsl:function name="geo:point3" as="xs:integer+">
<xsl:param name="location3" as="element(diggs:Hole)"/>
<xsl:variable name="point3" as="xs:string"
select="$location3/diggs:location/gml:Point/gml:pos"/>
<xsl:sequence select="xs:integer(substring-before($point3, ' '))"/>
<xsl:sequence select="xs:integer(substring-after($point3, ' '))"/>
</xsl:function>
</xsl:stylesheet>
The main parts to focus on in both files are where I've commented in <!-- Ground Layers --> , so in the xml you are looking at the <geo:groundLayers> and it's children and in the xsl you are looking at <!-- Ground layer variables -->, <!-- diagram for ground layers --> and <!-- Ground layer function --> (at bottom).
.
The output of those two files is:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"
width="900px"
height="600px"
version="1.1"
viewBox="0 0 1700 1100"
preserveAspectRatio="xMinYMin">
<g transform="translate(50,150)">
<g id="gLayers">
<path id="groundLayer1" stroke-width="2" stroke="black" fill="none"
d="M0 0 L 0 0, 363 299, 574 499, 901 549, 901 400, 574 449, 363 599, 0 599z"/>
<path id="groundLayer2" stroke-width="2" stroke="black" fill="none"
d="M0 400 L 0 400, 363 449, 363 550, 0 449z"/>
<path id="groundLayer3" stroke-width="2" stroke="black" fill="none"
d="M0 550 L 0 550, 363 449, 574 599, 901 599, 901 750, 574 769, 363 769, 0 769z"/>
</g>
</g>
</svg>
I use Saxon-B 9.1.0.3 to transform to the above. I then open it using Safari 4 beta and Firefox 3 (to see they both view the same..and so far they do).
The problem areas are highlighted in bold and basically are the y coordinates used for plotting the ground layer's path on the return leg (i.e. uses layerBaseDepth in equations and not layerTopDepth.) I have checked that the xml data is correct and it is. So the problem is definitely with the xslt.
If you change the output paths to the following then it will be correct:
Code:
<g id="gLayers">
<path id="groundLayer1" stroke-width="2" stroke="black" fill="none"
d="M0 0 L 0 0, 363 299, 574 499, 901 549, 901 599, 574 599, 363 449, 0 400z"/>
<path id="groundLayer2" stroke-width="2" stroke="black" fill="none"
d="M0 400 L 0 400, 363 449, 363 449, 0 550z"/>
<path id="groundLayer3" stroke-width="2" stroke="black" fill="none"
d="M0 550 L 0 550, 363 449, 574 599, 901 599, 901 769, 574 769, 363 769, 0 750z"/>
</g>
So all the difference here is is that the bold values have been ordered the opposite way.
When you look at the xml code that determines this, then what it tells me is that the variable $posb is not applying correctly to altitudeGL and layerBaseDepth. But the ordering is working directly on distanceGL (as that doesnt need the variable) as the x-values are correctly ordered.
Any other info then please let me know.
Last edited by jamesdurham; March 16th, 2009 at 10:16 AM..
Reason: Cut a few more bits of code out
|
|

March 16th, 2009, 11:18 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Here is an adapted stylesheet. It changes the intermediate result a bit by introducing an element called 'layer-data' for each item in the group where then the data like 'distanceGL' is stored. Using that changed structure you can do an inner for-each select="layer-data" with an xsl:sort and access the data like distanceGL in the right order. At least the result is now what you described above.
Code:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:math="http://exslt.org/math"
xmlns:geo="www.dur.ac.uk/geo-engineering" xmlns:gml="http://www.opengis.com/gml/3.2"
exclude-result-prefixes="xs math geo gml diggs" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:diggs="http://www.diggml.com">
<!-- Used to define that all elements' white space to be removed -->
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" doctype-public="-//W3C//DTD SVG 1.1//EN"
doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"/>
<!-- Leaves CDATA sections in output -->
<xsl:output cdata-section-elements="script style"/>
<xsl:template match="/">
<xsl:apply-templates mode="svg"/>
</xsl:template>
<xsl:template match="geo:slopeData" mode="svg">
<svg width="900px" height="600px" version="1.1" viewBox="0 0 1700 1100"
preserveAspectRatio="xMinYMin">
<xsl:apply-templates select="geo:case" mode="svg"/>
</svg>
</xsl:template>
<xsl:template match="geo:case" mode="svg">
<!-- Level 1 Variables -->
<xsl:variable name="toe" as="xs:integer+" select="geo:point(geo:slope/geo:toe/geo:location)"/>
<xsl:variable name="crest" as="xs:integer+"
select="geo:point(geo:slope/geo:crest/geo:location)"/>
<xsl:variable name="diff" as="xs:integer+" select="$toe[1] - $crest[1], $toe[2] - $crest[2]"/>
<xsl:variable name="distance" as="xs:integer"
select="xs:integer(round(math:sqrt($diff[1] * $diff[1] + $diff[2] * $diff[2])))"/>
<xsl:variable name="altitude" as="xs:integer+" select="(//geo:Height)"/>
<xsl:variable name="height" as="xs:integer">
<xsl:choose>
<xsl:when test="$altitude[1] < 0">
<xsl:value-of select="$altitude[2] - $altitude[1]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$altitude[2] - $altitude[1]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="angle" as="xs:integer"
select="xs:integer(round(57.2957795*(math:atan2($height, $distance))))"/>
<!-- Level 2 Variables -->
<xsl:variable name="m1" as="xs:decimal" select="$diff[2] div $diff[1]"/>
<xsl:variable name="c1" as="xs:decimal" select="$toe[2] - (($m1)*$toe[1])"/>
<!-- y1=(m1*x) + c -->
<xsl:variable name="m2" as="xs:decimal" select="-1 div $m1"/>
<xsl:variable name="mdiff" as="xs:decimal" select="$m2 - $m1"/>
<!-- Ground layer variables -->
<xsl:variable name="groundLayers" as="element(layer)*">
<xsl:for-each-group
select="geo:slope/geo:groundLayers/diggs:Hole/diggs:layerSystems/diggs:LayerSystem/diggs:layers/diggs:Layer"
group-by="diggs:id">
<xsl:sort select="current-grouping-key()"/>
<layer xmlns="">
<xsl:variable name="layerName" select="diggs:primaryName"/>
<xsl:variable name="layerId" select="diggs:id" as="xs:integer"/>
<xsl:variable name="layerDescription"
select="diggs:descriptions/diggs:Description/diggs:value"/>
<layerId>
<xsl:value-of select="$layerId"/>
</layerId>
<layerDescription>
<xsl:value-of select="$layerDescription"/>
</layerDescription>
<layerName>
<xsl:value-of select="$layerName"/>
</layerName>
<xsl:for-each select="current-group()">
<layer-data>
<xsl:variable name="layerTopDepth" select="diggs:top/gml:pos"/>
<xsl:variable name="layerBaseDepth" select="diggs:base/gml:pos"/>
<xsl:variable name="groundLayer" as="xs:integer+"
select="parent::diggs:layers/parent::diggs:LayerSystem/parent::diggs:layerSystems/parent::diggs:Hole/geo:point3(.)"/>
<xsl:variable name="coordinateX1" as="xs:integer" select="$groundLayer[1]"/>
<xsl:variable name="coordinateY1" as="xs:integer" select="$groundLayer[2]"/>
<xsl:variable name="c2" as="xs:decimal"
select="$groundLayer[2] - (($m2)*$groundLayer[1])"/>
<xsl:variable name="cdiff" as="xs:decimal" select="$c1 - $c2"/>
<xsl:variable name="xi" as="xs:decimal" select="$cdiff div $mdiff"/>
<xsl:variable name="yi" as="xs:decimal" select="($m2*$xi)+$c2"/>
<xsl:variable name="xdiff" as="xs:decimal" select="$toe[1] - $xi"/>
<xsl:variable name="ydiff" as="xs:decimal" select="$toe[2] - $yi"/>
<xsl:variable name="distanceGL"
select="xs:integer(round(math:sqrt($ydiff * $ydiff + $xdiff * $xdiff)))"
as="xs:decimal"/>
<xsl:variable name="heightGL" as="xs:integer"
select="parent::diggs:layers/parent::diggs:LayerSystem/parent::diggs:layerSystems/preceding-sibling::diggs:location/geo:height"/>
<xsl:variable name="altitudeGL" as="xs:integer">
<xsl:choose>
<xsl:when test="$altitude[1] < 0">
<xsl:value-of select="$heightGL - $altitude[1]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$heightGL - $altitude[1]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<heightGL>
<xsl:value-of select="$heightGL"/>
</heightGL>
<distanceGL>
<xsl:value-of select="$distanceGL"/>
</distanceGL>
<altitudeGL>
<xsl:value-of select="$altitudeGL"/>
</altitudeGL>
<coordinateX1>
<xsl:value-of select="$coordinateX1"/>
</coordinateX1>
<coordinateY1>
<xsl:value-of select="$coordinateY1"/>
</coordinateY1>
<layerTopDepth>
<xsl:value-of select="$layerTopDepth"/>
</layerTopDepth>
<layerBaseDepth>
<xsl:value-of select="$layerBaseDepth"/>
</layerBaseDepth>
</layer-data>
</xsl:for-each>
</layer>
</xsl:for-each-group>
</xsl:variable>
<!--
<debug>
<xsl:copy-of select="$groundLayers"/>
</debug>
-->
<!-- Diagram for ground layers -->
<g transform="translate(50,150)">
<g id="gLayers">
<xsl:for-each select="$groundLayers">
<xsl:variable name="layerId" select="layerId"/>
<xsl:variable name="layerDescription" select="layerDescription"/>
<xsl:variable name="layerName" select="layerName"/>
<path id="groundLayer{$layerId}" stroke-width="2" stroke="black" fill="none">
<xsl:attribute name="d">
<xsl:for-each select="layer-data">
<xsl:sort select="xs:double(distanceGL)" order="descending"/>
<xsl:if test="position() eq 1">
<xsl:text>M</xsl:text>
<xsl:value-of select="$distance - distanceGL"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$height - altitudeGL + layerTopDepth"/>
</xsl:if>
</xsl:for-each>
<xsl:text> L </xsl:text>
<xsl:for-each select="layer-data">
<xsl:sort select="xs:double(distanceGL)" order="descending"/>
<xsl:value-of
select="concat($distance - distanceGL, ' ', (($height - altitudeGL) + layerTopDepth))"/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>, </xsl:text>
<xsl:for-each select="layer-data">
<xsl:sort select="xs:double(distanceGL)" order="ascending"/>
<xsl:variable name="posb" select="position()"/>
<xsl:value-of
select="concat($distance - distanceGL, ' ', (($height - altitudeGL) + layerBaseDepth))"/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>z</xsl:text>
</xsl:attribute>
</path>
</xsl:for-each>
</g>
</g>
</xsl:template>
<!-- Level 1 Function -->
<xsl:function name="geo:point" as="xs:integer+">
<xsl:param name="location" as="element(geo:location)"/>
<xsl:variable name="point" as="xs:string" select="$location/gml:Point/gml:pos"/>
<xsl:sequence select="xs:integer(substring-before($point, ' '))"/>
<xsl:sequence select="xs:integer(substring-after($point, ' '))"/>
</xsl:function>
<!-- Ground Layer Function -->
<xsl:function name="geo:point3" as="xs:integer+">
<xsl:param name="location3" as="element(diggs:Hole)"/>
<xsl:variable name="point3" as="xs:string"
select="$location3/diggs:location/gml:Point/gml:pos"/>
<xsl:sequence select="xs:integer(substring-before($point3, ' '))"/>
<xsl:sequence select="xs:integer(substring-after($point3, ' '))"/>
</xsl:function>
</xsl:stylesheet>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

March 16th, 2009, 11:32 AM
|
|
Authorized User
|
|
Join Date: Mar 2009
Posts: 50
Thanks: 7
Thanked 0 Times in 0 Posts
|
|
That's amazing work, thank you ever so much!
I'm perhaps more amazed that you can read through my code and make enough sense out of it in order to help!
I shall look at all of the changes closely and learn from them. I'll then extend the xml data to a more realistic problem to see if it stands the test. But from what I can see and having checked the resultant code, seems it will.
I will post back the result of all of this here when it's mostly done and online (should be within a few days). The actual useable versions of it for other users will hopefully be ready in a few weeks. Your input on it at the end would be appreciated as you certainly know what you're talking about!
These diagrams are aids to show and represent slope information (mostly in relation to slope instability scenarios). All of the other information is text-based and is shown as such on xhtml pages.
Thanks you again!
|
|
 |