У меня уже был подобный вопрос, но он немного сложнее.
Я пытаюсь получить текстовый результат некоторых данных геологического слоя из XML с помощью xslt.
Образец 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.
Я ищу способ сгруппировать по атрибуту STRAT конкретного INTV, и результат должен выглядеть так (скажем, из набора данных 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" в группировке.
Поскольку на этот вопрос частично ответили здесь: XSLT группирует братьев и сестер с условиями?
но я сделал ошибку в своем примере, я задал новый вопрос для этого нового сканирования.
Я надеюсь, что моя идея дойдет до конца, и я продолжу поиски.
Спасибо за помощь.
Привет, Майкл, спасибо за вопрос. Да, сценарий возможен. В STRAT может быть в основном все, что может придумать человек :) я немного отредактирую набор данных в этом отношении :) еще раз спасибо
Чтобы получить результат, который вы показываете, вы можете сделать довольно простую корректировку ответа на свой предыдущий вопрос:
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
, однако это невозможно (по крайней мере, если вы хотите использовать мюнховский метод группировки), потому что в XSLT 1.0 вам не разрешено использовать переменную в шаблоне сопоставления.
Эй, майкл, кажется, это работает так, как задумано :) Да, параметризация INTV - часть моей идеи, но я тоже могу жить без этого :) Я был удивлен, что ты это заметил :) Большое спасибо, я попробую реализовать + настроить часть в всю таблицу стилей и желаю всего наилучшего ;) Ты гений.
Какой процессор вы используете?
msxml6, в основном то, что поставляется с Microsoft Windows:/
Я пытаюсь внедрить ваши шаблоны в мои уже существующие, и, похоже, у них конфликт/работает только один шаблон. Знаете ли вы, как использовать несколько шаблонов и упорядочивать их? у меня все на match = "/*".
Боюсь, я не смогу ответить на это в комментарии. Возможно, это может помочь: lenzconsulting.com/how-xslt-работает.
эй, спасибо :) я смотрю на это. но эти шаблонные правила, похоже, являются причиной моей проблемы. плохо попробую разобраться.
Эй, я разместил вопрос с некоторым набором данных здесь: stackoverflow.com/questions/72141180/…, может быть, моя идея лучше объяснена там?
Возможно ли, чтобы СЛОЙ, INTV которого равен нет 1, имел STRAT, которого нет ни у одного LAYER с INTV, равным 1?