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.

¿Fue útil?

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(. &lt; ../../*/@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.

Eche un vistazo a esto . Luego úsalo en tu xpath

/root/item[@navorder = math:max(/root/item/@navorder)]

O algo similar :)

NOTA Esto requiere el uso de EXSLT .

NOTA 2 : No, no lo hace. Simplemente copie y pegue el código.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top