Subject: Re: [xsl] Re: Re: The Perils of Sudden Type-Safety in XPath 2.0 From: "Kurt Cagle" <kurt@xxxxxxxxxxxxx> Date: Thu, 20 Feb 2003 01:42:21 -0800 |
Dimitre, I'm not disagreeing with your position. I have had some fundamental objections to the introduction of data-typing within XSLT almost from the moment that it first appeared in the specifications. I've worked with XSLT often enough to state that the number of times I can point to where static typing would have come in handy can be counted on one hand, and usually there was some work-around there. I see the type mechanisms as a big step backwards, but one that is unfortunately driven by a few vendors (principally Microsoft) who are convinced that dynamic typing is bad and dangerous. I can think of a few cases where I would agree, but many more where dynamic typing is far preferable to dealing with static type. As to the function mapping, I'm a little more ambivalent. The example I gave there was pedagogical in nature, meant to illustrate the principle. I do believe, however, that the principle advantage that there are two principle advantages of the <xsl:function> element: 1) It makes it easier to develop a consistent set of libraries that can be utilized repeatedly. You may end up using this function only once in a given stylesheet, but if you use the same function imported into multiple stylesheets then you've significantly reduced your overhead. 2) It makes it possible to create class-like architectures within well defined namespaces, a definite plus as I see it in creating a comprehensive framework for development. For instance, you can define a matrix namespace: <!-- matrix.xsl --> <xsl:stylesheet xmlns:xsl="..." xmlns:mat='http://www.mynamespaces.com/mat' version='2.0'> <xsl:function name="mat:new"> </xsl:function> <xsl:function name="mat:cross_product"> ... </xsl:function> <xsl:function name="mat:dot_product"> ... </xsl:function> <xsl:function name="mat:add"> </xsl:function> ... </xsl:stylesheet> Given that, you've essentially created an object called matrix: with an associated set of methods. <xsl:stylesheet xmlns:xsl="..." xmlns:matrix='http://www.mynamespaces.com/mat' version='2.0"> <xsl:import href="matrix.xsl"/> <xsl:template match="foo"> <xsl:variable name="mat1" select="matrix:new(3,3,(1,1,0,0,1,0,-1,0,1))"/> <xsl:variable name="mat2" select="matrix:new(3,3,(1,0,1,1,1,0,1,1,0))"/> <xsl:variable name="matResult" select="matrix:add($mat1,$mat2)"/> ... </xsl:template> </xsl:stylesheet> Admittedly, you've inverted the traditional class structure somewhat: $mat1.add($mat2) becomes matrix:add($mat1,$mat2), but this to me is a relative formality. Most significantly in the above case, you've created an abstraction mechanism - you don't need to know what the underlying structure of a matrix object is, only that it behaves consistently. Perhaps as importantly, a structure is introduced without needing to have any explicit typing mechanism in place. Now, the question can legitimately be asked about whether I'd want to do complex matrix mathematics in XML, though to be honest I don't think it is as far fetched as it sounds. I could definitely see it being used in X3D generation, for instance. At any rate, this library serves to not only abstract out the underlying implementation (I could, for instance, use an external Java class or C# class to do the actual matrix multiplication, depending upon platform) but also to more intelligently organize functions. This gets me back to a gripe that I've had about the XPath2/XQuery functions, one which, to date, I've still not received a satisfactory answer about (other than "oh, it's too late to make changes at this point", told to me about six months ago). There are a huge number of date functions within the specs, that seem to cause no end of trouble from an implementation standpoint, and that seem to provide relatively little benefit save as mechanisms to more easily extract date content. It seems to make so much more sense to me to build an import facility into XQuery akin to <xsl:import> (something that's frankly a necessity anyway, since the same argument about the utility of "one-off" functions in XSLT2 applies to XQuery in spades) and then put the date functions (including the date types, more on that in a moment) into their own namespace. In XSLT, you'd have: <!-- dateTime.xsl --> <xsl:transform ... xmlns:dateTime=http://www.w3.org/xquery/ns/dateTime> <xsl:function name="new"> ... </xsl:function> <xsl:function name="get_month"> ... </xsl:function> <xsl:function name="get_full_year"> ... </xsl:function> <!-- and so forth --> </xsl:transform> <!-- dateTimeTest.xsl --> <xsl:stylesheet ... xmlns:dateTime="http://www.w3.org/xquery/ns/dateTime"> <xsl:template match="foo"> <xsl:variable name="myDate" select="dateTime:new('2003-02-18T00:00:00')"/> <xsl:variable name="month" select="dateTime:get_month($myDate)"/> <xsl:variable name="year" select="dateTime:get_full_year($myDate)"/> </xsl:template> </xsl:stylesheet> In XQuery you'd use a similar syntax: import namespace 'http://www.w3.org/xquery/ns/dateTime' as 'dateTime' let $myDate:=dateTime:new("2003-02-18T00:00:00") return <date> <month>{dateTime:get_month($myDate)}</month> <year>{dateTime:get_full_year($myDate)}</year> </date> In a situation like this, the namespace prefixes essentially act like class identifiers. It gives you "type" characteristics, avoids namespace collisions, reduces the size of the core XQuery/XPath2 function spec to about a third of its present size, and allows for extensibility. You can also use it to create more effective wrapper functions. For instance, you could create a double: namespace that encapsulates the xsi:double data-type: <xsl:transform ... xmlns:double='http://www.w3.org/xquery/ns/double'> <xsl:function name="double:new"> .... </xsl:function> <xsl:function name="double:value". ... </xsl:function> <xsl:function name="double:toInteger". ... </xsl:function> <xsl:function name="double:toString"> ... </xsl:function> </xsl:transform> This would let you do <xsl:variable name="dbl" select="double:new(100.5)"/> <xsl:variable name="result" select="double:value($dbl) * 110.2"/> <xsl:value-of select="double:toString($result)"/> or, in XQuery, let $dbl :=double:new(100.5) let $result := double:value($dbl) * 110.2 return <result>{double:toString($result)}</result> The other advantage to this approach is that you can define a set of standard conversion functions for each data type in this way that are able to sense the appropriate context and map implicitly (i.e., $dbl is equivalent to double:value($dbl) when forced into a cast with a double, double:toString($dbl) when forced into a cast with a string, and so forth. Yes, it is marginally more verbose, but at least if you're remotely familiar with OOP it makes a lot more sense than trying to create a superlibrary with no underlying organization on that library. -- Kurt ----- Original Message ----- From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx> To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx> Sent: Thursday, February 20, 2003 12:18 AM Subject: Re: [xsl] Re: Re: The Perils of Sudden Type-Safety in XPath 2.0 > > --- "Kurt Cagle" <cagle@xxxxxxxxx> wrote: > > Dmitre, > > > > I'm inclined to agree with Michael on this. I think that the type > > mechanisms > > do add (perhaps an unreasonable) burden in verbosity, but that is > > more > > than > > offset by the ability to move a significant amount of the heavy > > lifting > > into > > XPath through <xsl:function> > > > > <xsl:function name="fmt:bangPad"> > > <xsl:param name="expr"/> > > <xsl:result > > select="string-pad('!',xs:string(xs:integer($expr)))"/> > > </xsl:function> > > > > <xsl:value-of select="fmt:bangPad(@risk * @severity)"/> > > > > Kurt, > > This is a nice example! > > But the truth probably lies somewhere in-between. > > There will be cases when many functions are used in a stylesheet, but > most of them are used *only once*. Providing a wrapper xsl:function for > every such function will increase the length of the code significantly. > > One can argue that probably third-party libraries of such wrappers will > be available, so one will need only to xsl:import them. > > But if this happens, this would mean that something in the design of > the standard functions was not OK. > > Let's return to the example of string-pad(). Would it not be a better > decision to allow any number as the type of the second argument? > > Then people would have to use the familiar conversion number(x) and > this would facilitate the transition to XSLT2 for most of the XSLT1 > folks. Let's face it -- most people (me included) do not feel > comfortable that they must use schemas with XSLT2. Even declaring the > namespace and using the prefix can be a considerable psychological > burden (sorry for going into Jeni's territory). > > This will also address Chuck's concern that the XSLT2 programmer will > have to do an "awful lot of cross-referencing to grok it all (go look > at the XQuery function and operator spec, then go look at XPath, then > go back to the XSLT spec to see how to use something else)". > > And let's not try to mislead anyone that xs:integer was chosen because > it was the exact type for this function -- it isn't the exact type. > Anyone can still pass a negative integer to string-pad() and no static > type-checking will help. > > So, the authors of XQ/XP functions/operators decided to draw the line > somewhere, but should have drawn it on allowing any number, not just > integer. > > Probably we need to start some real work using Saxon 7.x and have a > separate forum for discussing the real-work experience. > > I also will join the people appreciating highly the huge work done by > Mike Kay and his advice on XSLT2 (and not least having to deal with > people like myself :o)) > > > > > > ===== > Cheers, > > Dimitre Novatchev. > http://fxsl.sourceforge.net/ -- the home of FXSL > > __________________________________________________ > Do you Yahoo!? > Yahoo! Tax Center - forms, calculators, tips, more > http://taxes.yahoo.com/ > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Re: Re: The Perils of Sud, Dimitre Novatchev | Thread | RE: [xsl] Re: Re: The Perils of Sud, Michael Kay |
Re: [xsl] variable scope and test d, Dimitre Novatchev | Date | Re: [xsl] Should You Comment XSLT A, Agnes Kielen |
Month |