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

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

Namespace fixup also ensures that every element has a namespace node that maps the prefix
xml
to the namespace URI
http://www.w3.org/XML/1998/namespace
. At any rate, this is what the specification says. In practice, implementations probably won't store a real node for this namespace; instead, they will simply behave as if it always existed.

Namespace Inheritance

It's worth observing one thing that namespace fixup
doesn't
do. When you create an element

as a child of

, namespace fixup does not try to give the

element a copy of every namespace node that is present for the

element. This is controlled instead by the
[xsl:]inherit-namespaces
attribute of the instruction that creates the

element.

XML Namespaces 1.1 introduces the ability to undeclare namespaces. It was always possible under XML Namespaces 1.0 to write:

which has the effect that the
http://one.com/ns
namespace is in scope for

but not for

. This is represented in the data model by the fact that the

element has a namespace node that maps the empty prefix to the namespace URI
http://one.com/ns
, while the

element has no such namespace node. With XML Namespaces 1.1 it becomes possible to do the same thing with a nondefault namespace. You can now write:


   


Again, this is represented in the data model by the fact that the

element has a namespace node that maps the prefix
one
to the namespace URI
http://one.com/ns
, while the

element has no such namespace node. However, if the above code appears in your stylesheet rather than your source document, then the

element will acquire a copy of the namespace node
xmlns:one=“http://one.com/ns”
as part of the process of element construction. This is because, by default, when an element is attached as a child to a new parent, it (and its descendants) acquire copies of all the namespace nodes that are present on the new parent, unless they actually bind the same prefix to a different namespace. This process is called
namespace inheritance
. If you want to disable this, you need to write:


   


You'll only really notice the difference if you put this structure in a variable and then use an instruction such as

. If namespace nodes are inherited, the result will be:


But if namespace nodes are not inherited, the result will be:


When you serialize the

element as an XML 1.0 document, it's not possible to represent the absence of the namespace, so the result will be the same either way, namely:

If you want a faithful representation of the tree, showing that the namespace is not in scope for the

element, you will need to serialize the result as an XML 1.1 document; moreover, you will have to explicitly say that you want to take advantage of this XML 1.1 feature by specifying the serialization parameter
undeclare-prefixes=“yes”
. If you do this, the output will be:



   


For more details of serialization options, see

on page 420, and Chapter 15.

Validating and Annotating the Element

This section is relevant only if you are using a schema-aware XSLT processor. With a non-schema-aware processor, you cannot use the
type
and
validation
attributes, and the type annotation on the new element will always be
xs:untyped
, which you can effectively ignore because it imposes no constraints.

With a schema-aware processor, you can validate the new element to ensure that it conforms with relevant definitions in a schema. If validation fails, a fatal error is reported. If it succeeds, the new element will have a type annotation that reflects the validation that was performed. This type annotation will not affect the way the element node is serialized, but if you want to do further processing on the element, the type annotation may affect the way this works. For example, if you sort a sequence of elements annotated with type
xs:integer
, you will get different results than if they are annotated as
xs:string
.

If you use the
type
attribute, the value of the attribute must be a lexical QName that identifies a known type definition. Generally, this means that it must either be a built-in type such as
xs:string
or
xs:dateTime
, or it must be the name of a global simple or complex type defined in a schema that has been imported using an

declaration in the stylesheet. (That is, the local part of the QName must match the
name
attribute of a top-level

or

element in a schema document whose target namespace matches the namespace URI part of the
QName
.)

The XSLT specification allows the implementation to provide other ways of accessing type definitions, perhaps through an API or a configuration file, and it also allows the type definition to originate from a source other than an XML Schema, but since it provides no details of how this might work, we won't explore the possibility further here.

The processor validates that the constructed element conforms to the named type definition. If it does, the element is annotated with the name of this type. If it doesn't, processing fails.

Validating an element is a recursive process, which also involves validating all its attributes and child elements. So these contained elements and attributes may also acquire a different type annotation.

In general, it's likely that some of the contained elements and attributes will be validated against anonymous type definitions in the schema, that is, types defined inline as part of another type definition (or element or attribute declaration), rather than named global types. In this case, the XSLT processor invents a name for each such type definition and uses this invented name as the type annotation. The invented name is not visible to the application, though it might appear in diagnostics, but it is used during subsequent processing whenever there is a need to check that the element or attribute conforms to a particular type. (In practice, of course, the invented “name” might not really be a name at all, but a pointer to some data structure containing the type definition.)

There is potentially a lot of redundant processing if you validate every element that you add to the result tree, because elements at the bottom level of the tree will be validated repeatedly each time an ancestor element is validated. It's up to the XSLT processor to handle this sensibly; one approach that it might use is to mark the element as needing validation, but to defer the actual validation until it really needs to be done.

Validating the element may also have other effects; in particular, it may cause default values for elements and attributes within the element's content to be expanded. Default values can be defined in the schema using

or

. So the element after validation may contain element and attribute values that were not put there explicitly by the stylesheet.

Other books

Hard Candy by Andrew Vachss
First Degree Innocence by Simpson, Ginger
The Truth Against the World by Sarah Jamila Stevenson
Secrecy by Rupert Thomson
Some Kind of Hell by London Casey
Piercing the Darkness by Peretti, Frank
Tears of War by A. D. Trosper
The Biographer by Virginia Duigan
Dark Secret by Christine Feehan