#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()]
, будет совпадающим элементом (или последним оставшимся элементом).