xsl:value-of


The <xsl:value-of> instruction constructs a text node, and writes it to the result sequence.

Changes in 2.0

In XSLT 2.0 the value to be output can be obtained by evaluating a contained sequence constructor as an alternative to using the select attribute.

A separator attribute has been added, allowing a sequence of values to be output separated by spaces, commas, or any other convenient string.

Format

 <xsl:value-of    select? = expression    separator? = { string }    disable-output-escaping? = "yes"  "no"> <!-- content:  sequence-constructor  --> </xsl:value-of> 

Position

<xsl:value-of> is an instruction. It is always used as part of a sequence constructor.

Attributes

Name

Value

Meaning

select optional

Expression

The value to be output

separator optional

Attribute value template returning a string

A string to be used to separate adjacent items in the output

disable-output-escaping optional

«yes » «no »

The value «yes » indicates that special characters in the output (such as «< » ) should be output as is, rather than using an XML escape form such as «&lt; » . The default value is «no »

Content

If the select attribute is present, the element must be empty. Otherwise, it may contain a sequence constructor.

Effect

The expression is evaluated. In general, this produces a sequence. This sequence is atomized, which causes any nodes in the sequence to be replaced by their typed values.

If the sequence is empty, the result of the <xsl:value-of> instruction is a text node containing a zero-length string. Text nodes are allowed to be zero-length so long as they have no parent. But if you try to use a zero-length text node to form the content of an element, the text node disappears in the process.

If the sequence contains a single value, this is converted to a string (by applying the XPath 2.0 casting rules). A new text node is constructed with this string as its value, and the text node is returned as the result of the <xsl:value-of> instruction (which usually means it will be written to a result tree). If the sequence (after atomization) contains more than one item, then the effect depends on whether backwards compatibility mode is enabled. This depends on the nearest version or xsl:version attribute found on a containing element, known as the effective version. If the effective version is less than «2.0 » , then backwards compatibility mode is in force. However, if there is a separator attribute, then the instruction behaves according to the XSLT 2.0 rules regardless of the effective version.

Under the backwards compatibility rules, any item after the first in the sequence is discarded, and the function behaves as if the sequence only contained one item (the rules for this have already been described).

Under the 2.0 rules, each value in the atomized sequence is converted to a string by applying the XPath casting rules, and these strings are concatenated , with the chosen separator inserted between adjacent strings. Unless this concatenated string is zero-length, a new text node is constructed that contains this string as its value, and the text node is returned as the result of the instruction.

The default separator (under the 2.0 rules) is a single space when the select attribute is used, or a zero-length string when a sequence constructor is used. This means that

  <a><xsl:value-of select="1 to 5"/></a>  

will output

  <a>1 2 3 4 5</a>  

but:

  <a>   <xsl:value-of>[<xsl:sequence select="1 to 5"/>]</xsl:value-of>   </a>  

will output:

  <a>[12345]</a>  

The disable-output-escaping attribute has the same effect as it has with <xsl:text> . Special characters such as «< » in the string value of the select expression will be escaped just as if they occurred in literal text, and the disable-output-escaping attribute can be used to suppress this in the same way. For details, see <xsl:text> on page 459.

Usage

The <xsl:value-of> element is the most common way of writing text to a result tree.

The other ways of writing text nodes to the result tree are to include text literally in the stylesheet (perhaps within an <xsl:text> instruction) or to use <xsl:copy> or <xsl:copy-of> . You could generally make do without using <xsl:value-of> at all, because <xsl:value-of select="X" separator="Y"/> is in most cases equivalent to <xsl:copy-of select=" string-join (X, 'Y')''/> . The slight difference between the two is that <xsl:value-of> always returns a text node, whereas <xsl:copy-of> in this example returns a string; but in most situations, these are interchangeable.

Another alternative is to use <xsl:apply-templates> on a text node and rely on the built-in template for text nodes, which is equivalent to <xsl:value-of select="."/> .

The <xsl:value-of> instruction is often an effective alternative to navigating the source tree recursively using <xsl:apply-templates> . For example:

  <xsl:template match="book">   <book>   <publisher><xsl:value-of select="../@name"/></publisher>   <title><xsl:value-of select="@title"/></title>   <author><xsl:value-of select="@author"/></author>   <isbn><xsl:value-of select="@isbn"/></isbn>   </book>   </xsl:template>  

You will often see <xsl:value-of> being used when there is actually no need to create a text node, for example when returning a result from a called template. This is because in XSLT 1.0, there was nothing better available. For example it is common to write a named template that replaces characters in a filename as follows :

  <xsl:template name="change-filename">   <xsl:param name="filename"/>   <xsl:value-of select="translate($filename, '\', '/')"/>   </xsl:template>  

But in XSLT 2.0 it would be better to return a string rather than a text node:

  <xsl:template name="change-filename">   <xsl:param name="filename"/>   <xsl:sequence select="translate($filename, '\', '/')"/>   </xsl:template>  

Either way, however, the template can then be called as follows, to get the result into the variable $new-filename :

  <xsl:variable name="$new-filename    ">    <xsl:call-template name="change-filename">   <xsl:with-param name="$old-filename"/>   </xsl:call-template>   </xsl:variable>  

The value of variable $new-filename is actually a temporary tree, but for all practical purposes it can be treated as a string. In fact, it would be better to declare it as a string:

  <xsl:variable name="$new-filename" as="xs:string">   <xsl:call-template name="change-filename">   <xsl:with-param name="$old-filename"/>   </xsl:call-template>   </xsl:variable>  

When the requirement is to return a string, there is no point in creating a text node and then letting the caller extract the string value of the text node. Although it all happens automatically, you are asking the system to do more work than is necessary.

  The option to use the sequence constructor to obtain the value, rather than   the select attribute, is provided mainly to make <xsl:value-of> compatible   with other instructions such as <xsl:attribute> and <xsl:comment>. It does   not add any important new capability.  

Avoiding Surprises

There are two situations in which <xsl:value-of> might not give the result you expect.

The first should be less common with XSLT 2.0 than it was with 1.0, but it will still happen in stylesheets that specify «version="1.0" » and thus invoke backwards compatibility mode. This is the fact that only the first item in a sequence is actually output. For example, if the context node is a <book> element and you specify <xsl:value-of select="author"/> , only the first author (in document order) will actually be output. This changes when you specify «version="2.0" » : All the authors are now output, using a single space as the default separator.

Of course, if you have become accustomed to the 1.0 behavior, then the surprise might be the other way around. If your stylesheet specifies <xsl:value-of select="following-sibling::para"/> , then when you change it to say «version="2.0" » , the output will contain all the following sibling paragraphs rather than just the first. You can easily correct this by changing it to <xsl:value-of select="following-sibling::para[1]"/> .

The second situation that sometimes causes surprise is typified by the question "Why have all the tags disappeared?" If you use <xsl:value-of> to output an element such as a <para> element that contains complex or mixed content, then it will extract the value of this element as a string. If there are nested elements, for example elements marked up by tags such as <i> or <b> , then these are lost in the course of converting to a string. If you want these tags to appear in the output, then use <xsl:copy-of> to copy the element, not <xsl:value-of> .

This situation may also change in XSLT 2.0 if you use a schema-aware processor. If the select expression selects an element, and the element is described in the schema as having complex element-only content, then atomization will raise a runtime error. For example if the source document contains the element:

  <book>   <title>XSLT 2.0 Programmer's Reference</title>   <author>Michael Kay</author>   <publisher>Wiley</publisher>   </book>  

then with a processor that is not schema-aware (or an XSLT 1.0 processor), the instruction <xsl:value-of select="book"/> will produce the output:

  XSLT 2.0 Programmer's ReferenceMichael KayWiley  

But with a schema-aware processor, assuming the schema declaration is:

  <xs:element name="book">   <xs:complexType>   <xs:sequence>   <xs:element name="title" type="xs:string"/>   <xs:element name="author" type="xs:string"/>   <xs:element name="publisher" type="xs:string"/>   </xs:seguence>   </xs:complexType>   </xs:element>  

the result will be a runtime error. If you want to concatenate the text nodes within the <book> element then you can still do so, using the string() function, but it's not something that atomization will do automatically for you. This is because, for data-oriented XML, it doesn't usually make sense. With mixed content however (where text and markedup elements can be freely mixed in the content) it does make sense to extract the textual content without the markup, and <xsl:value-of> will do this whether or not there is a schema.

Mixed content is described in the schema using <xs:complexType mixed=" true "> .

Using disable-output-escaping

One technique used quite often is to wrap HTML inside an XML document, for example:

  <message>   <header>   <sent-by>Dept 178</sent-by>   <recipient>App 263</recipient>   </header>   <content type="text/html">   <![CDATA[   <html>   <head><title>An HTML page with unmatched tags</title></head>   <body>HTML authors are often lazy!<p></body>   </html>   ]]>   </content>   </message>  

One way you can include the HTML within the XML message is to put it through a program such as Dave Raggett's html tidy utility (available from http://www.w3.org/ ), which converts it to well- formed XHTML. But you may not want to risk changing it, so using a CDATA section as shown here is the only alternative. When you do this, however, the «< » and «> » characters are no longer treated as mark up characters, they are now ordinary text. If you try to run an XSLT transformation that outputs the HTML enclosed in this message, these characters will therefore be escaped, typically by writing them as «&lt; » and «&gt; » . This isn't what you want; so you can solve the problem by writing:

  <xsl:template match="content[@type='text/html']">   <xsl:value-of select="." disable-output-escaping="yes"/>   </xsl:template>  

But remember that this is likely to work only if the output is serialized by the XSLT processor; it won't work if you write the result to a DOM.

Examples

The table below shows some common ways in which <xsl:value-of> is used.

Instruction

Effect

<xsl:value-of select="."/>

Output the string value of the current node

<xsl:value-of select="title"/>

Output the string value of the first child <title> element of the current node

<xsl:value-of select="sum(@*)"/>

Output the sum of the values of the attributes of the current node, converted to a string. If there is any non-numeric attribute, the result will be "NaN"

<xsl:value-of select="$x"/>

Output the value of variable $x , after converting it to a string

See Also

  • <xsl:copy-of> on page 245

  • <xsl:text> on page 459




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