Re: The Perils of Sudden Type-Safety in XPath 2.0
Hi Chuck, > I'm only now starting to play around with XSLT 2.0, so this is a > question I am posing to you , not an argument. Can you give me an > example where automatic casting takes place? I tried to create one > multiplying two values and assumed, based on this thread, it would > return an integer, but it didn't happen. Can you clarify the > situation for my muddled mind? I'm not exactly sure what you're asking for, but here's an example that illustrates what happens when you multiply two values under XSLT 2.0. Say you had the following unvalidated (and hence untyped) XML: <problem risk="3" severity="4">...</problem> and you wanted to create a number of exclamation marks equal to the value of @risk * @severity. @risk and @severity are both always integers, but the XML is untyped so the XSLT processor doesn't know this. Since neither @risk nor @severity is typed, an XSLT 2.0 processor will assume that since you want to multiply them together they must be of type xs:double. When you multiply two doubles, the result is a value of type xs:double. If you try to use a double as an argument or operand to a function or operator that expects an integer (or indeed most other types), you will get a type error. For example, if you try to do: <xsl:value-of select="string-pad('!', @risk * @severity)" /> or: <xsl:for-each select="1 to @risk * @severity">!</xsl:for-each> then you will get errors because string-pad() expects an integer as its second argument and the 'to' operator expects integers for its arguments. You have to do one of: - add types to your document by validating it against a schema or by creating a temporary tree in which the attributes are assigned types - cast the values to integers explicitly within the code - use a variable to create an untyped node containing the value which will then be automatically cast to the right type Explicit casts look like: <xsl:value-of select="string-pad('!', xs:integer(@risk * @severity))" /> Creating the variable looks like: <xsl:variable name="danger"> <xsl:value-of select="@risk * @severity" /> </xsl:variable> <xsl:value-of select="string-pad('!', $danger)" /> This latter works because the $danger variable holds the document node of a tree that contains the value of @risk * @severity. The typed value of the document node is the value 7 of the type xdt:untypedAtomic [*]. Since the type is xdt:untypedAtomic, the value is cast automatically to the required type of xs:integer when the variable is used. Cheers, Jeni [*] I mistakenly talked about the type xdt:anyAtomicType in an earlier mail when I meant xdt:untypedAtomic. --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format