xsl: для каждой группы не дает мне границ групп, включенных в группы

#xslt #xslt-2.0 #xslt-grouping

#xslt #xslt-2.0 #xslt-группировка

Вопрос:

Я преобразую математические формулы из одного проприетарного формата в другой. Основная проблема заключается в том, что в исходном формате перечислены элементы в том порядке, в котором они появляются, где целевой формат использует логическое определение в соответствии со строгим содержанием MathML (но совсем не то же самое — в данном случае даже XML).

Следующая формула:

 <FORMULA>
  <EXPR>A</EXPR>
  <OP.CMP TYPE="EQ"/>
  <EXPR>B</EXPR>
  <OP.CMP TYPE="EQ"/>
  <EXPR>C</EXPR>
</FORMULA>
  

Стало бы:

 equal[char[A],char[B],char[C]]
  

Это довольно просто, но когда ТИП второго OP.CMP отличается от первого, он меняется:

 <FORMULA>
  <EXPR>A</EXPR>
  <OP.CMP TYPE="EQ"/>
  <EXPR>B</EXPR>
  <OP.CMP TYPE="NE"/>
  <EXPR>C</EXPR>
</FORMULA>
  

Становится:

 equal[char[A],notequal[char[B],char[C]]]
  

Поскольку внутри каждого из них много вложенных уровней, мне нужно обработать формулу, сначала сгруппировав элементы, используя операторы OP.CMP и OP.MATH в качестве границ группы. Тогда я бы выбрал тип операции.CMP или OP.MATH для запуска группы. Но когда я использую xml: для каждой группы, заканчивающейся на OP.CMP или OP.MATH, я не нахожу OP.CMP или OP.MATH включены в группу, чего я и ожидал. Вот мой простой тест XSL:

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">

<xsl:template match="FORMULA" mode="eqn">
    <xsl:for-each-group select="node()" group-ending-with="OP.CMP">
        <xsl:message>Group <GRP><xsl:copy-of select="."/></GRP></xsl:message>
    </xsl:for-each-group>
</xsl:template>
  

Что я получаю, так это:

Group <GRP><EXPR>A</EXPR></GRP>

Группа <GRP><EXPR>B</EXPR></GRP>

Group <GRP><EXPR>C</EXPR></GRP>

где я ожидал этого:

Group <GRP><EXPR>A</EXPR><OP.CMP TYPE=»EQ»/></GRP>

Group <GRP><EXPR>B</EXPR><OP.CMP TYPE=»NE»/></GRP>

Group <GRP><EXPR>C</EXPR></GRP>

Является ли элемент, который завершает группу, не включенным в эту группу? Если да, есть ли что-то еще, что я должен использовать вместо этого?

Ответ №1:

Внутри элемента for-each-group контекста . находится первый элемент в каждой группе, а не полная группа; полная группа, к которой вы можете получить доступ current-group() , в случае group-ending-with элемента current-group()[last()] , будет совпадающим элементом (или последним оставшимся элементом).