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> </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 中,您不允许在匹配中使用变量模式 .
我已经有类似的问题了,但那个问题有点复杂。
我正在尝试使用 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> </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 中,您不允许在匹配中使用变量模式 .