Encuentra el valor máximo del nodo
Pregunta
Tengo un xml a continuación:
<root title="الصفحة الرئيسة">
<item title="الصفحة الرئيسة" itemuri="tcm:8-29-4" ShowInNav="True" type="sg" pageuri="tcm:8-10592-64" sLink="/ara/index.aspx">
<item title="من نحن" itemuri="tcm:8-779-4" ShowInNav="True" type="sg" pageuri="tcm:8-9934-64" navorder="00500" sLink="/ara/about/index.aspx">
</item>
<item title="برامجنا" itemuri="tcm:8-817-4" ShowInNav="True" type="sg" pageuri="tcm:8-10112-64" navorder="00100" sLink="/ara/courses/language-study-abroad.aspx">
</item>
<item title="مدارسنا" itemuri="tcm:8-824-4" ShowInNav="True" type="sg" pageuri="tcm:8-10162-64" navorder="00300" sLink="/ara/schools/english-language.aspx">
</item>
</item>
</root>
Ahora quiero el valor máximo de navorder , de modo que pueda usar ese valor aún más en " si " condición.
Solución
A continuación se muestra el código XSLT 1.0 de dos posibles soluciones .
Una tercera solución es usar EXSLT .
Una cuarta solución es usar la plantilla maximum
de FXSL .
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="vMax1" select=
"*/*/*/@navorder[not(. < ../../*/@navorder)][3]"/>
$vMax1: <xsl:value-of select="$vMax1"/>
<xsl:variable name="vMax2">
<xsl:call-template name="max">
<xsl:with-param name="pSeq"
select="*/*/*/@navorder"/>
</xsl:call-template>
</xsl:variable>
$vMax2: <xsl:value-of select="$vMax2"/>
</xsl:template>
<xsl:template name="max">
<xsl:param name="pSeq"/>
<xsl:variable name="vLen" select="count($pSeq)"/>
<xsl:if test="$vLen > 0">
<xsl:choose>
<xsl:when test="$vLen = 1">
<xsl:value-of select="$pSeq[1]"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vHalf"
select="floor($vLen div 2)"/>
<xsl:variable name="vMax1">
<xsl:call-template name="max">
<xsl:with-param name="pSeq"
select="$pSeq[not(position() > $vHalf)]"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="vMax2">
<xsl:call-template name="max">
<xsl:with-param name="pSeq"
select="$pSeq[position() > $vHalf]"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$vMax1 >= $vMax2">
<xsl:value-of select="$vMax1"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$vMax2"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Cuando la transformación anterior se aplica en el documento XML original:
<root title="الصفحة الرئيسة">
<item title="الصفحة الرئيسة" itemuri="tcm:8-29-4"
ShowInNav="True" type="sg"
pageuri="tcm:8-10592-64"
sLink="/ara/index.aspx">
<item title="من نحن" itemuri="tcm:8-779-4"
ShowInNav="True" type="sg"
pageuri="tcm:8-9934-64"
navorder="00500"
sLink="/ara/about/index.aspx"/>
<item title="برامجنا" itemuri="tcm:8-817-4"
ShowInNav="True" type="sg"
pageuri="tcm:8-10112-64"
navorder="00100"
sLink="/ara/courses/language-study-abroad.aspx"/>
<item title="مدارسنا" itemuri="tcm:8-824-4"
ShowInNav="True" type="sg"
pageuri="tcm:8-10162-64"
navorder="00300"
sLink="/ara/schools/english-language.aspx"/>
</item>
</root>
se produce el resultado deseado:
$vMax1: 00500
$vMax2: 00500
Otros consejos
la siguiente es una solución que usa XPath 1.0:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="maximum">
<xsl:value-of select="/root/item//item[not(preceding-sibling::item/@navorder > @navorder or following-sibling::item/@navorder > @navorder)]/@navorder"/>
</xsl:variable>
<max>
<xsl:value-of select="$maximum"/>
</max>
</xsl:template>
</xsl:stylesheet>
La expresión
/root/item//item[not(preceding-sibling::item/@navorder > @navorder or following-sibling::item/@navorder > @navorder)]/@navorder
filtra todos los nodos de elementos para que no haya ningún nodo anterior o siguiente que tenga un valor de navegador más alto en el mismo nivel.
Encontré esta publicación en el foro como una posible solución .
Por supuesto, si tiene acceso a XPath 2.0, hay una solución más directa: fn: max (arg, arg, & # 8230;)
Un par de formas: con xpath 2 puedes usar la función max (), pero si estás en xslt 1 tendrás que usar ordenar en un para cada uno y luego colocar el elemento en la posición 1 en su variable.