5.5 . Number Core Function Group

The number functions all return a number as their function return type. It contains five functions, one of which, number(), serves as the fundamental conversion of any object to a number.

The five functions in the number core function group are covered below, beginning with the number() conversion function, which takes an optional object argument to be converted to a number. This function is similar to string() and boolean() in that it works ubiquitously under the hood while not frequently being explicitly called itself. Following this is the sum() function, which serves to convert a required node-set object's string value to a number. The remaining three functions include a top-end test of a given numerical sequence, the ceiling() function, a bottom-end test, the floor() function, and the round() function, to which we referred earlier.

5.5.1. The number() Function

The number() function is the primary conversion function used to convert an object to a number. It has one optional argument of type object, as shown in the following function prototype. If no argument is supplied, the default is the current node.

Function: number number(object?)
Function Name Core Function Group Returns Arguments Argument Type
number() Number Number Object optional

The number() function is implicitly used in any other function that returns a number, such as the count() function in the node-set core function group or the string-length() function in the string core function group. Accordingly, number() is not often called on its own.

Because the argument to the number() function is of type object, any of the four object types, node-set, string, Boolean, or number can be used. Converting each of these object types to a number has a specific set of rules, which are covered in the next section.

5.5.2. Number Conversion Rules

The four object types, node-set, string, Boolean, or number can be converted to a number following the conversion rules specified by the W3C XPath recommendation (section 4.4) as follows.

  1. A string that consists of optional whitespace followed by an optional minus sign followed by a Number followed by whitespace is converted to the IEEE 754 number that is nearest (according to the IEEE 754 round-to-nearest rule) to the mathematical value represented by the string; any other string is converted to NaN.

    This basically says that if the string looks like a number, it is converted to that number. Whitespace is stripped, and the value is given for that number according to IEEE 754 and rounding; otherwise it is not a number, and the string is NaN in its numerical value.For example, using our Markup City, number(//block) will return the value NaN because the resolved value of //block returns a string that is not numbers, the text value of the node. If the resolved value of an expression is a string that looks like a number, it can be converted to a number for use by other functions that are expecting a number. For example, number('1235') returns the number 1235, which can then be interpreted by another function.

    A more useful example includes using number(substring('1st Street', 1, 1)) to extract the street number from the element <block>1st Street</block>, using the substring() and number() functions.

    This would return the number 1. If you did not use the number() function, the returned value would be the string "1."

  2. Boolean true is converted to 1; boolean false is converted to 0.

    This rule follows basic “bit” rules where 0 is off and 1 is on; a 1 (the existence of something) will always be true, a 0 (the absence of something) will always be false.[8] Recall from our contains() example that we had an expression that returned a true value. If we wrap that same function in the number() function, number(contains('xml', 'x')), the result will be to convert the string true to a number 1.

    [8] What that “something” is can be potentially fuel conversations on existentialism. What does it mean to be something that signifies nothing? One has to wonder, do bits and bytes ask “why am I here?”

  3. A node-set is first converted to a string as if by a call to the string() function and then converted in the same way as a string argument.

    Node-sets are converted to a string according to the string conversion rules in Section 5.3.2, in which the node-set's first node is converted to a string and its string-value is then converted to a number according to the string-to-number conversion rules (see 1 above). Again, if the resulting string is not a number, the value will be NaN.

  4. An object of a type other than the four basic types is converted to a number in a way that is dependent on that type.

    The fact that there can be other types of objects leaves the interpretation of the conversion of those objects up to the creator of those objects. If a new object type is created and managed, for example, by an extension element, the namespace for that extension should supply the conversion rules for that object.

5.5.3. The sum() Function

The sum() function adds the value of each node in a node-set, after it has been converted to a number. This of course means that the nodes in the node-set being converted must contain numbers or digits; otherwise the result of this function will be NaN. The sum() function returns a number as a function return type. It requires a single argument of a type node-set, as shown in the following function prototype. The node-set supplied will be converted to a number according to the conversion rules for node-sets, mentioned in the previous section on number().

Function: number sum(node-set)
Function Name Core Function Group Returns Arguments Argument Type
sum() Number number Node-set required

If our Markup City had yet another set of streets, perhaps in the French Quarter, called <rue>s, we could then use the sum() function to add up the contents of the <rue> elements,[9] as shown in Example 5-18.

[9] This summing up of a node-set could get quite complicated if there were elements of the same name nested inside each other, for example if our Markup City was in Bangkok, where a side street is called a soi and a soi can get big enough to have its own branching sois.

Example 5-18. XML for the sum() function example.
<parkway>
      <thoroughfare>Governor Drive</thoroughfare>
      <thoroughfare name="Whitesburg Drive">
            <sidestreet>Bob Wallace Avenue</sidestreet>
            <block>1st Street</block>
            <block>2nd Street</block>
            <block>3rd Street</block>
            <sidestreet>Woodridge Street</sidestreet>
      </thoroughfare>
      <thoroughfare name="Concord">
            <rue>47</rue>
            <rue>48</rue>
            <rue>49</rue>
      </thoroughfare>
</parkway>

FUNCTION:


sum(//rue)

TEMPLATE RULE:

<xsl:template match="/">
<xsl:value-of select="sum(//rue)"/>
</xsl:template>

Using the sum() function would return the value of the sum of 47, 48, and 49, which is equal to 144.

5.5.4. The ceiling() Function

The ceiling() function finds the nearest integer—that is, not a decimal number—larger than the number supplied as its argument. In effect, it works like a rounding function that always rounds up. It has one required argument, which is of type number, as shown in the following function prototype.

The ceiling() function is one of a pair with a complimentary function, the floor() function, discussed immediately below. The ceiling() function operates on numbers or objects that are converted to numbers prior to processing.

Function: number ceiling(number)
Function Name Core Function Group Returns Arguments Argument Type
ceiling() Number number Number required

In effect, the ceiling() function is like the round() function, except the ceiling() function will find the nearest possible integer that is greater than the input argument. For example, the function call ceiling(2.8), would return 3; the ceiling() for 2.1 is also 3. Negative numbers work the same as rounding, finding the nearest negative integer greater than the argument; ceiling(-36.3) would be 36, and so on.

The ceiling() function is similar to round(), except that ceiling() always rounds up, whereas the round() function rounds up or down, depending on the number.

5.5.5. The floor() Function

The floor() function provides a sort of backward rounding functionality. It finds the nearest integer—that is, not a decimal number—smaller than the number supplied as its argument. Where normal rounding goes upward or downward, depending on the number, floor() always rounds down, finding the smallest integer nearest to the input argument. The floor() function has one required argument, which is a number, as shown in the following function prototype. It is one of a pair with a complimentary function, the ceiling() function, and performs the reverse of ceiling().

Function: number floor(number)
Function Name Core Function Group Returns Arguments Argument Type
floor() Number Number Number required

For example, the function call floor(2.8) returns a value of 2, and floor(2.1) is also 2. Using floor() with negative numbers, the rounding goes to the nearest integer in the opposite direction. For example, floor(-36.3) gives 37, which is the nearest integer still smaller than 36.3.

The floor() function is similar to round(), except that floor() always rounds down, whereas the round() function rounds up or down, depending on the number.

5.5.6. The round() Function

The round() function returns a number that is the result of rounding according to the rules specified in IEEE 754. It requires a single number input argument and operates on numbers or objects that are converted to numbers prior to processing. The following function prototype shows the structure of the round() function.

Function: number round(number)
Function Name Core Function Group Returns Arguments Argument Type
round() Number Number Number required

In XPath, rounding functions work the way you would normally expect rounding to work. The decimal counting idea of “5 or more rounds upward” is observed consistently. Accordingly, when using the function call substring(1.5), the result would be rounded up to 2, since 1.5 is not an integer, but 2 is. The rounding is always done to the nearest integer. Obviously, then, 1.8 would also round to 2, and 1.4 would round down to 1.

Things get more complicated with negative integers, however. An input argument of 0.5 up to 0 rounds to negative zero. Positive zero is always positive zero after rounding, and the same is true of negative zero. The same also holds for positive and negative infinity, which remain positive and negative infinity, respectively, when rounded. If the input argument is not a number, or NaN, then it remains NaN.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset