Finding max of three numbers in XSL

2019-07-26 20:40发布

问题:

How can find max of three numbers in XSL ? More Information : I have three numbers say 1.0, 2.0, 5.0....I don't have any nodes set... I would like to find maximum of 1.0, 2.0 and 5.0.....

Example :

AIM : TO know which type of node <MYNODE>, <DOC>, <PIC> 
is having maximum count and whant's the count number ?

    <ROOT>
              <MYNODES>
                   <MYNODE>A</MYNODE>
                   <MYNODE>B</MYNODE>
                   <MYNODE>C</MYNODE>
                   <MYNODE>D</MYNODE>
              </MYNODES> 
              <DOCS>
                   <DOC>1</DOC>
                   <DOC>2</DOC>
                   <DOC>3</DOC>
              </DOC> 
              <PICS>
                   <PIC>a.jpeg</PIC>
                   <PIC>b.jpeg</PIC>
                   <PIC>c.jpeg</PIC>
                   <PIC>d.jpeg</PIC>
                   <PIC>e.jpeg</PIC>
              </PICS> 
    </ROOT>

回答1:

This question is incorrectly formulated and the provided "XML document' is not well-formed!

Do note that it is generally meaningless to ask about the maximum of a set of numbers. There can be more than one number with the highest value. Therefore, the solutions below show just the first item with the maximum value.

This is one possible XSLT 1.0 solution:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

    <xsl:template match="/">
      <xsl:variable name="vNameMaxCount">
          <xsl:for-each select="*/*">
            <xsl:sort select="count(*)" data-type="number"
             order="descending"/>

             <xsl:if test="position() = 1">
                <xsl:value-of select="concat(name(),'+', count(*))"/>
             </xsl:if>
          </xsl:for-each>
      </xsl:variable>

      One element with maximum children is: <xsl:text/>
      <xsl:value-of select="substring-before($vNameMaxCount, '+')"/>

      Maximum number of children: <xsl:text/>
      <xsl:value-of select="substring-after($vNameMaxCount, '+')"/>

    </xsl:template>
</xsl:stylesheet>

when the above transformation is applied on the following XML document (produced from the one provided after spending 10 minutes to make it well-formed!):

<ROOT>
    <MYNODES>
        <MYNODE>A</MYNODE>
        <MYNODE>B</MYNODE>
        <MYNODE>C</MYNODE>
        <MYNODE>D</MYNODE>
    </MYNODES>
    <DOCS>
        <DOC>1</DOC>
        <DOC>2</DOC>
        <DOC>3</DOC>
    </DOCS>
    <PICS>
        <PIC>a.jpeg</PIC>
        <PIC>b.jpeg</PIC>
        <PIC>c.jpeg</PIC>
        <PIC>d.jpeg</PIC>
        <PIC>e.jpeg</PIC>
    </PICS>
</ROOT>

the wanted result is produced

  One element with maximum children is: PICS

  Maximum number of children: 5

An XSLT 2.0 solution (actually just an XPath 2.0 soulution):

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 >
 <xsl:output method="text"/>

 <xsl:template match="/">
   <xsl:sequence select=
    "for $vmaxChildrein in max(/*/*/count(*)),
         $vmaxNode in */*[count(*) = $vmaxChildrein][1]
      return 
         (name($vmaxNode), 
          'has the max no of children:', 
          $vmaxChildrein
          )
    "/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the above document, the wanted result is produced:

PICS has the max no of children: 5

For finding the maximum of more tricky properties that cannot be immediately expressed as an XPath expression and used in <xsl:sort>, do use the f:maximum() function of FXSL.



回答2:

With your input XML, you would find the maximum count you are looking for like this:

<xsl:variable name="vMaxChildren">
  <xsl:for-each select="/ROOT/*">
    <xsl:sort select="count(*)" data-type="number" order="descending" />
    <xsl:if test="position() = 1">
      <xsl:value-of select="concat(name(), ': ', count(*))" />
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

<xsl:value-of select="$vMaxChildren" />

Which would produce:

PICS: 5


回答3:

5.0 is the largest of the three numbers. Hardcode it and be done with it. :-)

Seriously though, you may wish to take another path. Logic like this is trivial in other languages, but can be a pain in XSLT. You should consider writing a simple extension for the XSLT engine rather than messing around trying to make XSLT do what you want it to.



标签: xslt