У вас странный реквизит ... На другом языке такая вещь, как бинарная древовидная структура, используется с алгоритмом как ваш для заказа или получения максимума.Это действительно не нужно в XSLT, потому что он имеет дело с деревьями и только с деревьями, поэтому в нем много встроенных алгоритмов, таких как сортировка.
Кроме того, это таблица стилей того, что я считаю желаемым преобразованием:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:param name="pReplace"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="pReplace" select="$pReplace"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="no[@value][descendant::no/@value]">
<xsl:param name="pReplace" select="''"/>
<xsl:variable name="vSwaped"
select="descendant-or-self::no
[contains($pReplace,
concat(generate-id(),
'+'))]"/>
<xsl:variable name="vPosition" select="count($vSwaped)+1"/>
<xsl:variable name="vReplace">
<xsl:for-each
select="(ancestor::no[$vSwaped]|
descendant-or-self::no)[@value]">
<xsl:sort select="@value"
data-type="number" order="descending"/>
<xsl:if test="position()=$vPosition">
<xsl:value-of select="concat(generate-id(),'+',@value)"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="value">
<xsl:value-of select="substring-after($vReplace,'+')"/>
</xsl:attribute>
<xsl:apply-templates select="node()">
<xsl:with-param name="pReplace"
select="concat($pReplace,
substring-before($vReplace,'+'),
'+',generate-id(),'|')"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="no[@value][not(descendant::no/@value)]" name="find">
<xsl:param name="pReplace" select="''"/>
<xsl:param name="pFind" select="generate-id()"/>
<xsl:variable name="vFound"
select="substring-before(
substring-after(
$pReplace,
concat($pFind,'+')),
'|')"/>
<xsl:choose>
<xsl:when test="$vFound!='' and $pFind != $vFound">
<xsl:call-template name="find">
<xsl:with-param name="pReplace" select="$pReplace"/>
<xsl:with-param name="pFind" select="$vFound"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="value">
<xsl:value-of select="//no[generate-id()=$pFind]
/@value"/>
</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Вывод:
<list>
<no value="111">
<no value="67">
<no value="56">
<no value="32"></no>
<no value="6"></no>
</no>
<no value="11">
<no value="8"></no>
<no value="9"></no>
</no>
</no>
<no value="11">
<no value="5"></no>
<no value="7"></no>
</no>
</no>
</list>
Объяснение : Родитель берет N-ую максиму своей ветви.N определяется как количество уже взятых максимумов из его ветви плюс один.Если из его ветви уже взят максимум, предки также принимаются в расчет максимума.Последние листья следуют по пути замен, чтобы найти их значение.
Это больше похоже на статическое отображение между входным состоянием и состоянием вывода, за исключением последних листьев.
Также обратите внимание, что I 'Мы используем очень общий шаблон, поэтому заботятся только о no
элементах с value
атрибутами.И могут быть любые другие элементы, которые они просто скопировали бы.