XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (83 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
2.06Mb size Format: txt, pdf, ePub

The
schema-location
attribute of

defines a URI where the schema document can be located. This is described in the specification as a hint, which means that if the XSLT processor knows a better place to look, it is free to do so. For example, it might already have a precompiled copy of the schema held in memory. If you don't supply a
schema-location
attribute, then the schema import will work only if the XSLT processor already knows where to look. It's possible, for example, that some XSLT processors might have built-in knowledge of common schemas such as the XHTML schema, so they never need to fetch the XML source. However, if you want your stylesheet to be portable, it's probably a good idea to specify the schema location.

You don't need to import schemas into every stylesheet module individually. Importing a schema into one stylesheet module makes its definitions available in all stylesheet modules. (This is a notable difference from the equivalent facility in XQuery.)

What happens if you have two

declarations for the same namespace URI (or, more probably, for the null namespace)? This can easily happen when different stylesheet modules are combined into a single stylesheet. Firstly, the system chooses the one with the highest import precedence, as explained in Chapter 3. If this leaves more than one, then they are all used. The XSLT specification explains how conflicts are resolved by reference to the XML Schema specification: it's defined to be the same as if you have two

declarations for the same namespace in a schema document. This is rather passing the buck, as it happens, because XML Schema leaves a lot of latitude to implementations in deciding how far they will go in analyzing two different schemas for conflicts. It's best not to do it. Because the processor is perfectly entitled to ignore the
schema-location
hint, it is also entitled to assume that if it already has a schema for a given namespace loaded, then this is the one that the user wanted.

As with validation, the XSLT specification describes the semantics of schema import by means of a rather artificial device: it describes an imaginary schema document that is assembled to contain

declarations representing each of the

declarations in the stylesheet. The reason for this artifice is that it provides a way of invoking the rules of XML Schema and saying that they apply equally to XSLT, without actually copying the rules and repeating them, which would inevitably lead to inconsistencies. No real implementation is likely to integrate the XSLT processor and the schema processor in the clumsy manner described in the spec.

You don't need to import a schema merely because it is used to validate source documents. However, I would recommend doing so. If you don't, this creates the possibility that a source document will contain type annotations that mean nothing to the XSLT processor. There are various ways an XSLT processor can deal with this problem (no less than four possible approaches are described in the specification, one of which is to raise an error), but the simplest approach is to avoid the problem by ensuring that all the schemas used in your transformation are explicitly imported.

With AltovaXML 2008, source documents are validated only if they contain an
xsi:schemaLocation
attrbibute that identifies the schema to be used.

Using xsi:type

I haven't yet mentioned the use of
xsi:type
in this chapter (I did mention
xsl:type
, but that's a completely different thing, despite the similar name). In fact, the XSLT 2.0 specification mentions
xsi:type
only in notes and examples, which means that it plays no formal role in the XSLT language. The
xsi:type
attribute is defined in the XML Schema specification—the prefix
xsi
is conventional, but the namespace URI must be
http://www.w3.org/2001/XMLSchema-instance
.

You can use
xsi:type
as an attribute on an element within a document that's being assessed by a schema processor. Its effect is to ask the schema processor to apply a stricter check to the element than it would otherwise. An
xsi:type
can't override the constraints defined in the schema, but it can make assertions about the document content that go beyond what the schema requires. For example, if the schema allows a particular element (by means of a union type) to contain either an integer or a QName, then specifying
xsi:type = “xs:QName”
will cause it to be validated as if only a QName were allowed. This can also result in the element node acquiring a more specific type annotation than would otherwise be the case.

The effect of
xsi:type
on schema validation applies just as much when the validation is happening under the control of XSLT as it does in freestanding schema processing. If you write an
xsi:type
attribute to the result tree (which you can do in exactly the same way as you write any other attribute), then the element will be validated against that type definition.

Although I started by saying that
xsi:type
and
xsl:type
were quite different things, this description shows that there are cases where their effects are very similar. For example, writing:

23.44

and:

23.44

can both produce a

element validated and annotated as being of type
xs:decimal
. However, there are some important differences:

  • xsl:type
    (or
    type
    ) invokes validation as well as specifying the expected type of the element.
    xsi:type
    specifies the expected type, but it is ignored unless validation is requested by some other mechanism.
  • The
    xsi:type
    attribute is copied to the result document; the
    xsl:type
    and
    type
    attributes are not.
  • The
    xsi:type
    attribute can only be used to specify the type of element nodes. A
    type
    attribute (when it is used on the

    instruction) can also control the type of attribute nodes.

Nillability

The
xsi:nil
attribute was defined in XML Schema because there were some people from the relational database tradition who felt that omitting an element or attribute from an XML document was not an adequate way of representing the SQL concept of null values. I have to say I find the facility completely unnecessary: null was invented in SQL so that a cell in a table could hold no data, but XML already has perfectly good ways of representing absence of data, namely an absent element or attribute. But
xsi:nil
exists, and it can't be uninvented, and you may need to use it if it has been built in to the semantics of the vocabulary for your source or result documents.

As with
xsi:type
, the
xsi:nil
attribute is mentioned in the XSLT specification only in notes and examples. However, it gets a rather more detailed treatment in the XPath formal semantics, because it has a significant effect in complicating the rules for type matching.

You can use
xsi:nil
on an element only if the schema defines the element as nillable. If you do set
xsi:nil = “true”
on an element, then the element is valid only if it is empty; moreover, it is allowed to be empty in this case even if the content model for the element would otherwise not permit it to be empty.

The possibility of encountering an
xsi:nil
potentially plays havoc with the type safety of your stylesheet. If you write a function that is designed to process valid book elements, and every book must have an ISBN, then the function should be allowed to access the ISBN without adding conditional logic to check that it is there. For this reason, a function or variable that accepts nilled elements has to declare that it does so. If a function parameter is declared with the type
as = “element(*, book-type)”
, then passing the element
xsi:nil = “true”/>
to this function will cause a type error. If you want to write a function that accepts this element, you must instead write
as = “element(*, book-type?)”
to show that your function can handle this input.

Other books

Behind the Eyes of Dreamers by Pamela Sargent
In Your Dreams Bobby Anderson by Maidwell, Sandra Jane
Time Quintet 04-Many Waters by Madeleine L'Engle
Irania by Inma Sharii
Reamde by Neal Stephenson
Carry On by Rainbow Rowell
What Alice Forgot by Liane Moriarty