tags:

views:

1226

answers:

5

Hi,

I have a xml given below:

<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>

Now I want to the value of maximum navorder, so that I can use that value further in "if" condition.

A: 

Have a look at this. Then use it in your xpath

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

Or something similar :)

NOTE This requires the use of EXSLT.

NOTE 2: No it doesn't. Just copy and paste the code.

OJ
its giving error given below:Error =System.Xml.Xsl.XsltException: Prefix 'math' is not defined. at System.Xml.Xsl.InputScopeManager.ResolveNonEmptyPrefix(String prefix)Please help
MKS
you'll have to add the math namespace
annakata
and you'll have to get / install the exslt extensions
0xA3
+1  A: 

I found this forum post as one potential solution.

Of course, if you have access to XPath 2.0, there's a more direct solution: fn:max(arg, arg, …)

Hank Gay
I am using xslt 1.0, please give examples using xslt 1.0
MKS
The link provided points to an XSLT/XPath 1.0 solution.
0xA3
A: 

Couple of ways: with xpath 2 you can use the max() function, but if you're in xslt 1 you'll have to use sort in a for-each and then put the item at position 1 in your variable.

annakata
can you please give one example with the given xml
MKS
my example would just be a template along the lines of OJ's solution
annakata
"plz email me teh codez" much?
Hank Gay
+1  A: 

Hi,

the following is a solution using XPath 1.0:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <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>

The expression

/root/item//item[not(preceding-sibling::item/@navorder > @navorder or following-sibling::item/@navorder > @navorder)]/@navorder

filters all item nodes so that there is no preceding or following node that has a higher navorder value on the same level.

0xA3
ha - the preceding/following sibling trick, yeah this is a good fast answer and should probably be accepted. The math:max template is possible a better general solution though.
annakata
However - as ususal with XPath/XSLT - such an expression will not be that efficient on large nodesets :-(
0xA3
+2  A: 

Below is the XSLT 1.0 code of two possible solutions.

A third solution is to use EXSLT.

A fourth solution is to use the maximum template of FXSL.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <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>

When the above transformatio is applied on the original XML document:

<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>

the wanted result is produced:

   $vMax1: 00500

   $vMax2: 00500
Dimitre Novatchev