"as" for global xsl:param / ...

  • Phil Pfeiffer

    Phil Pfeiffer - 2012-03-21

    Apologies for not posting this to dev.saxonica.com/community, but the site
    appears to be down this evening.

    Am I mistaken, or should it be possible to use an "as" clause to constrain the
    type of a command-line-supplied XSLT program parameter? I've just tried to
    <xsl:param name="level" as="xs:nonNegativeInteger" select="xs:nonNegativeInteger(1)"/>
    as a top-level statement instead of the usual
    <xsl:param name="level" select="1"/>
    in the hope of leveraging a run-time "as" check in order to simplify
    <xsl:template match="/">
    <xsl:when test="$level castable as xs:nonNegativeInteger" ?<br="">... do the desired thing ...
    <xsl:template match="/">
    .... do the desired thing ...

    Basically, this doesn't work. If (e.g.) I set "level" to "one", the run-time
    system fails to fail when my program starts. Instead, it generates a series of
    complaints (recoverable errors) about "one" not being convertable to an

    One other point about this logic puzzles me, as well. Why is it necessary to
    explicitly cast 1 as a datum of type xs:nonNegativeInteger when you specify an
    "as" clause of "xs:nonNegativeInteger"? This is one place where I'd want a
    language to do a coercion on my behalf, since there's no possible loss of
    precision that results from "downcasting" xs:integer(1) to

    -- Phil

  • Michael Kay

    Michael Kay - 2012-03-21

    Sorry for the prolonged downtime on the dev.saxonica.com site. We've rebuilt
    the server after a security breach but restoring the data has been taking
    longer than expected.

    I'm afraid the use of types like xs:nonNegativeInteger isn't very satisfactory
    in XSLT/XQuery. During the development of the language, I argued in favour of
    these being treated like predicates ("check that the integer is non-negative")
    but those who know a lot more about the theory of programming language type
    systems than I do, people like Phil Wadler, were very insistent that the type
    should be a label associated with the instance - "named typing" versus
    "structural typing" - so an integer is only a nonNegativeInteger if it is
    labelled as such. I agree with you that automatic downcasting of an xs:integer
    to an xs:nonNegativeInteger would make much more sense here. The one time you
    do get automatic casting, however, is if you supply an untypedAtomic value.

    However, on your first point, it's not obvious to me why the errors ("one" not
    being convertible) are treated as recoverable. Perhaps it's because you are
    using the value in a pattern - all errors during pattern matching are
    recoverable. Otherwise, I would need to see more detail on exactly what you
    are doing.

  • Phil Pfeiffer

    Phil Pfeiffer - 2012-03-23

    Thanks for replying as well as for the news about dev.saxonica.com.

    I was indeed using $level in a pattern, as part of a "match" attribute that
    counts a node's ancestors. It's part of a simple code that I was creating for
    a senior-level class on XML: a program that reverses elements at level n of a
    document for a user-specified n. The application will still make for an
    interesting discussion, now that I understand this point about recovering from
    type failures in patterns: the failure to enforce the "as" condition on $level
    on program entry would seem to be consistent with lazy evaluation.

    As for the point about typing, the comment about limiting type inference to
    what's provided by named typing is indeed helpful: thank you. Wadler's point,
    I would guess, would be that trying to accommodate special-case downcasting in
    a language that's already as rich as XSLT 2.0 would make the language that
    much harder to implement. Something else to tell my students...


    -- Phil


Log in to post a comment.