Find max node value

2019-06-25 04:07发布

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.

标签: xslt xpath
5条回答
再贱就再见
2楼-- · 2019-06-25 04:10

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.

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-06-25 04:12

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

查看更多
Lonely孤独者°
4楼-- · 2019-06-25 04:15

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, …)

查看更多
甜甜的少女心
5楼-- · 2019-06-25 04:16

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.

查看更多
干净又极端
6楼-- · 2019-06-25 04:31

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">
 <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
查看更多
登录 后发表回答