XSLT 根据条件对兄弟姐妹进行分组,第 2 部分?

XSLT grouping siblings with conditions, part2?

我已经有类似的问题了,但那个问题有点复杂。

我正在尝试使用 xslt 从 XML 中获取某些地质层数据的文本结果。

我得到的 XML 样本可能是这样的:

<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> 

类似2层描述,只是INTV属性值不同

我正在寻找一种方法来按特定 INTV 的属性 STRAT 进行分组,结果应该是这样的(假设来自 INTV= 1 数据集):

ZONE "geologiscal_formation_1" 0.00 95.00
ZONE "geologiscal_formation_2" 95.00 101.80 
ZONE "geologiscal_formation_3" 101.80 104.00  

棘手的部分是“忽略”分组中带有 EGART="Lost_Data" 的数据。

由于这个问题在这里得到了部分回答:

但是我在我的例子中犯了一个错误,我为那个新的 scanrio 做了一个新问题。

我希望我的想法得到通过,我会继续寻找。

感谢大家的帮助。

要获得您显示的结果,您可以对上一个问题的答案进行相当简单的调整:

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>&#10;</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>

请注意,我们在这里假设 LAYER@EGART='Lost_Data' 没有 STRAT 属性 - 因此可以在键定义中跳过此条件。

--
P.S。似乎您想对 INTV 的选择进行参数化 - 但是,这是不可能的(至少如果您想使用 Muenchian 分组方法则不可能),因为在 XSLT 1.0 中,您不允许在匹配中使用变量模式 .