i got a similar question already, but that one is a little more complicated.
I am trying to get a text result of some geological layer data from an XML using xslt.
The XML sample i got may look like that:
<LAYERS>
<LAYER DEPTHTO="1.00" PETRO="Sand" STRAT="geologiscal_formation_1" INTV="1"/>
<LAYER DEPTHTO="94.00" PETRO="Sand" STRAT="geologiscal_formation_1" INTV="1"/>
<LAYER DEPTHTO="94.20" INTV="1" INDEX_ZONE="-1" EGART="Lost_Data"/>
<LAYER DEPTHTO="95.00" PETRO="Gravel" STRAT="geologiscal_formation_1" INTV="1"/>
<LAYER DEPTHTO="100.00" PETRO="Sand" STRAT="geologiscal_formation_2" INTV="1"/>
<LAYER DEPTHTO="100.50" PETRO="Mud" STRAT="geologiscal_formation_2" INTV="1"/>
<LAYER DEPTHTO="101.50" PETRO="Sand" STRAT="geologiscal_formation_2" INTV="1"/>
<LAYER DEPTHTO="101.80" PETRO="Mud" STRAT="geologiscal_formation_2" INTV="1"/>
<LAYER DEPTHTO="102.90" PETRO="Mud" STRAT="geologiscal_formation_3" INTV="1"/>
<LAYER DEPTHTO="103.00" PETRO="Sand" STRAT="geologiscal_formation_3" INTV="1"/>
<LAYER DEPTHTO="103.25" INTV="1" INDEX_ZONE="-1" EGART="Lost_Data"/>
<LAYER DEPTHTO="103.69" PETRO="Sand" STRAT="geologiscal_formation_3" INTV="1"/>
<LAYER DEPTHTO="104.00" PETRO="Mud" STRAT="geologiscal_formation_3" INTV="1"/>
<LAYER DEPTHTO="1.00" PETRO="Sand" STRAT="geologiscal_formation_1" INTV="2"/>
<LAYER DEPTHTO="94.00" PETRO="Sand" STRAT="geologiscal_formation_1" INTV="2"/>
<LAYER DEPTHTO="94.20" INTV="2" INDEX_ZONE="-1" EGART="Lost_Data"/>
<LAYER DEPTHTO="95.00" PETRO="Gravel" STRAT="geologiscal_formation_2" INTV="2"/>
<LAYER DEPTHTO="100.00" PETRO="Sand" STRAT="geologiscal_formation_2" INTV="2"/>
<LAYER DEPTHTO="100.50" PETRO="Mud" STRAT="geologiscal_formation_4" INTV="2"/>
<LAYER DEPTHTO="101.50" PETRO="Sand" STRAT="geologiscal_formation_4" INTV="2"/>
<LAYER DEPTHTO="101.80" PETRO="Mud" STRAT="geologiscal_formation_5" INTV="2"/>
<LAYER DEPTHTO="102.90" PETRO="Mud" STRAT="geologiscal_formation_3" INTV="2"/>
<LAYER DEPTHTO="103.00" PETRO="Sand" STRAT="geologiscal_formation_3" INTV="2"/>
<LAYER DEPTHTO="103.25" INTV="2" INDEX_ZONE="-1" EGART="Lost_Data"/>
<LAYER DEPTHTO="103.69" PETRO="Sand" STRAT="geologiscal_formation_2" INTV="2"/>
<LAYER DEPTHTO="104.00" PETRO="Mud" STRAT="geologiscal_formation_2" INTV="2"/>
</LAYERS>
its like 2 layer descriptions, which only differ in the INTV attribute value.
Im looking for a way to group by attribute STRAT of specific INTV and a result should look like that (lets say from INTV= 1 dataset):
ZONE "geologiscal_formation_1" 0.00 95.00
ZONE "geologiscal_formation_2" 95.00 101.80
ZONE "geologiscal_formation_3" 101.80 104.00
The tricky part is to "ignore" the data with EGART="Lost_Data" in the grouping.
Since that question got partly answered here: XSLT grouping siblings with conditions?
but i made a mistake in my example, i did a new question for that new scanrio.
I hope my idea gets throu and ill keep searching.
Thanks for all help.
CodePudding user response:
To get the result you show, you could make a rather simple adjustment to the answer from your previous question:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="layer-by-strat" match="LAYER[@INTV=1]" use="@STRAT" />
<xsl:template match="LAYERS" >
<xsl:call-template name="generate-rows">
<xsl:with-param name="layers" select="LAYER[@INTV=1 and not(@EGART='Lost_Data')][count(. | key('layer-by-strat', @STRAT)[1]) = 1]"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="generate-rows">
<xsl:param name="layers" select="/.."/>
<xsl:param name="accumulated-depth" select="'0.00'"/>
<xsl:if test="$layers">
<xsl:variable name="strat" select="$layers[1]/@STRAT" />
<xsl:variable name="max-depth" select="key('layer-by-strat', $strat)[last()]/@DEPTHTO" />
<!-- output -->
<xsl:text>ZONE "</xsl:text>
<xsl:value-of select="$strat" />
<xsl:text>" </xsl:text>
<xsl:value-of select="$accumulated-depth" />
<xsl:text> </xsl:text>
<xsl:value-of select="$max-depth" />
<xsl:text> </xsl:text>
<!-- recursive call -->
<xsl:call-template name="generate-rows">
<xsl:with-param name="layers" select="$layers[position() > 1]"/>
<xsl:with-param name="accumulated-depth" select="$max-depth"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Note that we are assuming here that a LAYER
with @EGART='Lost_Data'
does not have a STRAT
attribute - so this condition can be skipped in the key definition.
--
P.S. It seems you would want to parametrize the choice of INTV
- however, that's not possible (at least not if you want to use the Muenchian grouping method) because in XSLT 1.0 you are not allowed to use a variable in a match pattern .