查找最大节点值

时间:2009-01-06 09:33:54

标签: xslt xpath

我在下面给出了一个xml:

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

现在我想要最大 navorder 的值,以便我可以在“ if ”条件下进一步使用该值。

5 个答案:

答案 0 :(得分:4)

以下是两种可能解决方案的XSLT 1.0代码

第三种解决方案是使用EXSLT

第四个解决方案是使用 FXSL maximum模板。

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

当上述转换应用于原始XML文档时:

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

产生了想要的结果:

   $vMax1: 00500

   $vMax2: 00500

答案 1 :(得分:2)

以下是使用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>

表达式

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

过滤所有项目节点,以便在同一级别上没有前导节点或后续节点具有更高的navorder值。

答案 2 :(得分:1)

我发现this forum post是一种潜在的解决方案。

当然,如果您可以访问XPath 2.0,那么可以使用更直接的解决方案:fn:max(arg, arg, …)

答案 3 :(得分:0)

看看this。然后在xpath中使用它

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

或类似的东西:)

注意这需要使用EXSLT

注意2 :不,不是。只需复制并粘贴代码即可。

答案 4 :(得分:0)

几种方式:使用xpath 2你可以使用max()函数,但是如果你在xslt 1中你必须在for-each中使用sort然后将项目放在位置变量中有1个。