如何使用xpath从多组计算值中获得最大值或最小值

时间:2013-04-04 20:42:51

标签: xslt xpath xslt-2.0 xpath-2.0

我最多需要三种三种值。 我有一个类似的结构。

注意:前两个答案基于前面的示例xml(在第2组中,最大 - 高于平均值为8)。这令人困惑,所以我将其改为7。

<data>
    <record>
        <max>60</max>
    </record>
    <day>
        <set>
            <average>49</average>
            <max-above-average>3</max-above-average>
        </set>
        <set>
            <average>45</average>
            <max-above-average>9</max-above-average>
        </set>
    </day>
    <night>
        <set>
            <average>50</average>
            <max-above-average>5</max-above-average>
        </set>
        <set>
            <average>52</average>
            <max-above-average>7</max-above-average>
        </set>
    </night>
</data>

现在我需要白天和黑夜的最大记录。这将是最大值:60,此示例中的记录值:60 = 60,&gt; 49 + 3,45 +9,50 + 5,52 + 7。需要计算日夜最大值。因为这个

  

max(// record / max | // day / set /(average + max-above-average))| // night / set /(平均值+最高 - 高于平均值))

不起作用。 | -sign仅适用于节点。 它给出了以下错误:

  

“|”的第二个操作数的必需项类型是node();提供的值具有项类型xs:double

我正在使用xpath 2.0和xslt 2.0。

2 个答案:

答案 0 :(得分:2)

以下是想要的两个XPath 2.0表达式(分别用于生成“max”和“min”值):

max(/*/(day|night)/*/(average+max-above-average))

min(/*/(day|night)/*/(average -min-above-average))

基于XSLT 2.0的验证

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
 max: <xsl:text/>
  <xsl:sequence select=
    "max(/*/(day|night)/*/(average+max-above-average))"/>
 min: <xsl:text/>
  <xsl:sequence select=
    "min(/*/(day|night)/*/(average -min-above-average))"/>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<data>
    <record>
        <min>40</min>
        <max>60</max>
    </record>
    <day>
        <set>
            <average>49</average>
            <max-above-average>3</max-above-average>
            <min-above-average>15</min-above-average>
        </set>
        <set>
            <average>45</average>
            <max-above-average>9</max-above-average>
            <min-above-average>2</min-above-average>
        </set>
    </day>
    <night>
        <set>
            <average>50</average>
            <max-above-average>5</max-above-average>
            <min-above-average>6</min-above-average>
        </set>
        <set>
            <average>52</average>
            <max-above-average>8</max-above-average>
            <min-above-average>11</min-above-average>
        </set>
    </night>
</data>

评估两个XPath表达式,并将这些评估的结果复制到输出

 max: 60
 min: 34

<强>更新

OP在评论中表示他希望“白天和晚上最多记录” - 我真的不明白他的意思。

这是我尝试猜测

max(
      (/*/record/max, 
       /*/(day|night)/*/(average+max-above-average, average+min-above-average)
       )
    )

当植入XSLT转换(上图)时,会产生:

 max: 64

答案 1 :(得分:1)

XSLT 1.0方法:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="/*">
    <xsl:variable name="recordMax" select="record/max" />
    <xsl:variable name="dayMax">
      <xsl:apply-templates select="day" mode="max" />
    </xsl:variable>
    <xsl:variable name="nightMax">
      <xsl:apply-templates select="night" mode="max" />
    </xsl:variable>

    <xsl:call-template name="Max">
      <xsl:with-param name="v1" select="$recordMax" />
      <xsl:with-param name="v2">
        <xsl:call-template name="Max">
          <xsl:with-param name="v1" select="$dayMax"  />
          <xsl:with-param name="v2" select="$nightMax" />
        </xsl:call-template>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="*[set]" mode="max">
    <xsl:apply-templates select="set" mode="max">
      <xsl:sort select="average + max-above-average"
                data-type="number"
                order="descending" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="set" mode="max">
    <xsl:if test="position() = 1">
      <xsl:value-of select="average + max-above-average" />
    </xsl:if>
  </xsl:template>

  <xsl:template name="Max">
    <xsl:param name="v1" />
    <xsl:param name="v2" />

    <xsl:choose>
      <xsl:when test="not($v2 > $v1)">
        <xsl:value-of select="$v1" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$v2" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

在样本输入上运行时,结果为:

60