xsl:namespace-alias


xsl: namespace-alias

The <xsl:namespace-alias> element allows a namespace used in the stylesheet to be mapped to a different namespace used in the output. It is most commonly used when writing transformations that produce an XSLT stylesheet as their output.

Changes in 2.0

The rules for generating namespace prefixes have been made stricter.

Format

 <xsl:namespace-alias   stylesheet-prefix = prefix  "#default"   result-prefix = prefix  "#default"/> 

Position

<xsl:namespace-alias> is a top-level declaration, which means it must be a child of the <xsl:stylesheet> element. It may be repeated any number of times in a stylesheet.

Attributes

Name

Value

Meaning

stylesheet-prefix

mandatory

NCName «#default »

A namespace prefix used in the stylesheet

result-prefix

mandatory

NCName «#default »

The prefix of the corresponding namespace to be used in the output

Content

None. The <xsl:namespace-alias> element is always empty.

Effect

The <xsl:namespace-alias> element affects the treatment of namespaces on literal result elements.

Normally, when an element node is output by processing a literal result element, the output element name will have the same local part, the same prefix, and the same namespace URI as those of the literal result element itself. It isn't guaranteed that it should have the same prefix, but it usually will. The same applies to the attributes of the literal result element. The namespace nodes on the literal result element must be copied unchanged to the result tree, using the same prefix and namespace URI. (The XSLT specification states that when processing a literal result element, all the namespaces that are in scope for the element in the stylesheet, with certain defined exceptions, will also be present in the output, even if they aren't used. Redundant namespace nodes can be suppressed by using the xsl:exclude-result-prefixes attribute. For more details on this, see the section Literal Result Elements, on page 106 in Chapter 3.)

Suppose you want the output document to be an XSLT stylesheet. Then you need to create elements such as <xsl:template> that are in the XSLT namespace. However, you can't use <xsl:template> as a literal result element, because by definition, if an element uses the XSLT namespace, it is treated as an XSLT element.

The answer is to use a different namespace on the literal result element in the stylesheet, and include an <xsl:namespace-alias> declaration to cause this to be mapped to the XSLT namespace when the literal result element is output. So your literal result element might be <out:template> , and you could use an <xsl:namespace-alias> element to indicate that the stylesheet prefix «out » should be mapped to the result prefix «xsl » .

The <xsl:namespace-alias> element declares that one namespace URI, the stylesheet URI, should be replaced by a different URI, the result URI, when literal result elements are output. The namespace URIs are not given directly, but are referred to by using prefixes that are bound to these namespace URIs as a result of namespace declarations that are currently in force. Either one of the namespace URIs may be the default namespace URI, which is referred to using the pseudoprefix «#default » . It's an error to use this if there is no default namespace defined.

So although the <xsl:namespace-alias> element describes the mapping in terms of prefixes, it is not the prefix that is changed, but the URI.

The substitution of one namespace URI for another affects the names of literal result elements themselves , and the names of all attributes of literal result elements. It also affects the URIs of namespace nodes copied into the result tree from a literal result element. It does not affect elements created using <xsl:element> , attributes created using <xsl:attribute> , or nodes copied using <xsl:copy> .

There was often confusion among XSLT 1.0 users about what namespaces they should expect to find declared in the result document, and different processors handled this differently. In XSLT 2.0, the rules have been clarified. Namespaces find their way from the stylesheet into the result document whenever a literal result element is evaluated. XSLT 2.0 states clearly that if the literal result element has a namespace node with the URI associated with the stylesheet-pref ix of an <xsl:namespace-alias> instruction, it is not copied to the result tree as it normally would be; if it has a namespace node with the URI associated with the result-prefix of an <xsl:namespace-alias> instruction, then this namespace node is copied, even if the URI is one such as http://www.w3.org/1999/XSL/Transform that would normally not be copied. These rules are designed to produce the result that most users would expect: A literal result element <out:template> will produce an element in the result tree that will normally be serialized as <xsl:template> ; the «xsl » namespace will be declared in the result document, and the «out » namespace will not be declared.

If there are several <xsl:namespace-alias> elements that specify the same stylesheet-prefix , the one with highest import precedence is used; a compile-time error is reported if there is more than one at the highest import precedence.

The aliasing of namespace URIs applies at the point when a literal result element in the stylesheet is evaluated to create an element node in a result sequence. It applies whether or not this element is written to a final result tree. This means that if you examine a temporary tree into which literal result elements have been copied, the corresponding elements and attributes will use the namespace URI associated with the result prefix, not the stylesheet prefix.

Aliasing of namespaces happens before the namespace fixup process described under <xsl:element> on page 265.

Usage and Examples

The main justification for this facility is to enable stylesheets to be written that generate stylesheets as output. This is not as improbable a scenario as it sounds; there are many possible reasons for using this technique, including the following:

  • There are many proprietary template languages currently in use. Translating these templates into XSLT stylesheets creates an attractive migration route, and there is no reason why these translators should not be written in XSLT.

  • There may be a continuing need for a template language, which is less complex and powerful than XSLT, for use by nonprogrammers. Again, these simple templates can easily be translated into XSLT stylesheets.

  • There are some parts of an XSLT stylesheet that cannot easily be parameterized. For example, it is not possible to construct an XPath expression programmatically and then execute it (XSLT is not a reflexive language). The requirement to do this arises when visual tools are developed to define queries and reports interactively. One way of implementing such tools is to construct a customized stylesheet from a generic stylesheet, and again this is a transformation that can be assisted by using XSLT.

  • You might have developed a large number of stylesheets that all have some common characteristic, for example they might all generate HTML that uses the <CENTER> tag. As the <CENTER> tag is deprecated, you now want to modify these stylesheets to use <DIV ALIGN="CENTER"> . Why not write an XSLT transformation to convert them?

  • There are tools that make it possible to generate XSLT stylesheets from a schema (see for example Schematron at http://www.ascc.net/xm l/resource/schematron/schematron.html ). Since both the schema and the stylesheet are XML documents, this is an XML-to-XML transformation, so it should be possible to write it in XSLT.

In fact, having gone through all the trouble of defining XSLT stylesheets as well- formed XML documents, it would be very surprising if it were impossible to manipulate them using XSLT itself.

However, it is possible to create stylesheets as output without recourse to <xsl:namespace-alias> : Just avoid using literal result elements, and use instructions such as <xsl:element name=" xsl:template "> instead. I personally find this approach less confusing, although the stylesheet ends up being more verbose.

There may be other situations where <xsl:namespace-alias> is useful. The XSLT specification mentions one, the need to avoid using namespace URIs that have recognized security implications in the area of digital signatures. Another might arise if stylesheets and other documents are held in a configuration management system; there might be a need to ensure that namespaces recognized by the configuration management system, for example to describe the authorship and change history of a document, are not used directly in the stylesheet.

It's also possible to define an alias for the xml namespace. For example, the following stylesheet ( xml-space.xsl ):

  <xsl:transform   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"   xmlns:axml="alias">   <xsl:namespace-alias stylesheet-prefix="axml" result-prefix="xml"/>   <xsl:template match="/">   <doc axml:space="preserve">text</doc>   </xsl:template>   </xsl:transform>  

produces the following output (regardless of the source document):

  <?xml version="1.0" encoding="UTF-8"?>   <doc xml:space="preserve">text</doc>  

This is useful because it gets an «xml:space="preserve" » attribute into the result document without affecting the way that whitespace is handled in the stylesheet.

A problem that causes a great deal of confusion with <xsl:namespace-alias> is the choice of prefixes in the result. Follow through exactly what happens when you write the stylesheet:

  <xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   xmlns:oxsl="old.uri">   <xsl:namespace-alias stylesheet-prefix="oxsl" result-prefix="xsl"/>   <xsl:template match="/">   <oxsl:stylesheet/>   </xsl:template>   </xsl:stylesheet>  

This transformation executes just one instruction: the <oxsl:stylesheet> literal result element. This has two namespace nodes, representing the prefix bindings «xmlns:xsl=" http://www.w3.org/1999/XSL/Transform " » and «xmlns:oxsl="old.uri" » (we will ignore the namespace node for the «xml » namespace). The first of these is copied to the result tree, because it matches the result-prefix , despite the fact that it would normally be an excluded namespace. The second namespace node is not copied, because its namespace URI ( «old.uri » ) is the one referred to by the stylesheet-prefix attribute. So the namespace node in the result tree will map the prefix «xsl » to the namespace URI « http://www.w3.org/1999/XSL/Transform » .

When the time comes to serialize this result tree, namespace nodes are used to generate namespace declarations, and prefixes are allocated to elements based on the prefixes found in namespace nodes for the element. So the output (ignoring the XML declaration) should be this:

  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>  

XSLT 2.0 (unlike 1.0) really doesn't give the implementation any latitude to generate anything else in this situation. In 1.0, there was a general rule that the serializer could add any namespace declarations it chose, and by implication that it could give elements and attributes any prefix that it chose. In 2.0, the namespace fixup process is only allowed to add namespaces if they are actually needed to make the tree consistent, and in this case, they aren't.

Example of <xsl: namespace-alias>
start example

The following example generates an XSLT stylesheet consisting of a single global variable declaration, whose name and default value are supplied as parameters. Although this is a trivial stylesheet, it could be useful when incorporated into another more useful stylesheet using <xsl:include> or <xsl:import> .

This example is available in the code download as alias.xsl .

Source

No source document is required. You can run this with Saxon 7.9 or later using the command:

  java -jar c:\saxon\saxon7.jar -it main alias.xsl  

The «-it » option on the command line causes the transformation to start at the template named «main » .

Stylesheet

  <xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   xmlns:xslt="output.xsl">   <xsl:param name="variable-name">v</xsl:param>   <xsl:param name="default-value"/>   <xsl:output indent="yes"/>   <xsl:namespace-alias   stylesheet-prefix="xslt"   result-prefix="xsl"/>   <xsl:template match="/" name="main">   <xslt:stylesheet version="1.0">   <xslt:variable name="{$variable-name}">   <xsl:value-of select="$default-value"/>   </xslt:variable>   </xslt:stylesheet>   </xsl:template>   </xsl:stylesheet>  

Output

If you default the values of the parameters «variable-name » and «default-value » , the output is as follows .

  <?xml version="1.0" encoding="utf-8"?>   <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   version="1.0">   <xsl:variable name="v"/>   </xsl:stylesheet>  
end example
 

See Also

Literal Result Elements in Chapter 3, on page 106.




XSLT 2.0 Programmer's Reference
NetBeansв„ў IDE Field Guide: Developing Desktop, Web, Enterprise, and Mobile Applications (2nd Edition)
ISBN: 764569090
EAN: 2147483647
Year: 2003
Pages: 324

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net