xsl:value-of

1. xsl:value-of
2. xsl:value-of vs xsl:copy-of
3. Value-of and copy-of - What's the difference?

1.

xsl:value-of

David Carlisle

the string value of an element node is the character data of _all_ its descendents.

<xsl:value-of select="text()"/> which is the character data of this element, or perhaps <xsl:value-of select="normalize-space(text()[1])"/> which is the first block of text, before the first element, with white space trimmed.

DaveP added a demo.

xml:

<?xml version="1.0" ?>
<RDF>
 <channel>first block of text
  <title>(Contained block of text)<
/title>Second block of text</channel>
 </RDF>
    
xsl:
<?xml version="1.0" ?> 

 <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     
     <xsl:output method="xml" indent="yes"/>
     
     
     <xsl:template match="/RDF">
    		 <xsl:apply-templates  />
         </xsl:template>
 
     <xsl:template match="channel">
===================================
Output from normalize-space(text()[1])
<xsl:value-of select="normalize-space(text()[1])"/>

Output from normalize-space(text()[2])
<xsl:value-of select="normalize-space(text()[2])"/>

====================================
Now output from value-of select= .
       <xsl:value-of select="."/>
===================================
Output from normalize-space(text())
<xsl:value-of select="normalize-space(text())"/>
===================================
Output from for-each select=text()
 <xsl:for-each select="text()">
  <xsl:value-of select="."/>
 </xsl:for-each>
</xsl:template>
 
</xsl:stylesheet>
      

Result:

<?xml version="1.0" encoding="utf-8"?>

 
===================================
Output from normalize-space(text()[1])
first block of text

Output from normalize-space(text()[2])
Second block of text

====================================
Now output from value-of select= .
       first block of text
  (Contained block of text)Second block of text
===================================
Output from normalize-space(text())
first block of text
===================================
Output from for-each select=text()
first block of text
  Second block of text

2.

xsl:value-of vs xsl:copy-of

Mike Brown

I just want to know the difference between xsl:value-of and xsl:copy-of

xsl:value-of creates a text node with the string-value of the selected or current node as the text node's value. consult the xpath spec for what the string-value is for each type of node.

xsl:copy-of creates a copy of the current or selected node and all its descendant nodes.

Mike Kay, being exact :-)

When the select expression is a node-set or a result-tree-fragment, xsl:value-of converts the expression to a string and puts it into a text node in the result tree, while xsl:copy-of generates nodes in the result tree that are copies of those selected.

3.

Value-of and copy-of - What's the difference?

David Carlisle

value-of and copy-of are the same thing on a text node (although it's normally fairly rare to access text nodes directly, some people tend to over-use text() it makes the stylesheet rather fragile as it means that source files with comments in often fail given

<foo>onetwo</foo>
<xsl:value-of select="foo"/> and <xsl:value-of select="foo/text()"/>

both generate a text node with value "onetwo". But given

<foo>one<!-- hmm -->two</foo>
<xsl:value-of select="foo"/> 

generates a text node with value "one two"

<xsl:value-of select="foo/text()"/> generates a text node with value "one two" in 2.0 mode or "one" in 1.0 compatibility mode.

So unless you intend your code to do something different in the presence of comments then it's usually better just to select the element.

> But is the following true: an element node's consists of the name of the
> element; a text node consists of the CDATA assigned to that node; But an
> attribute node consists of the name of an attribute *as well* as its CDATA -
> is this not inconsistent?

Nodes have various properties, as well as unique identies (element nodes can have the same name and content but are not equal (as tested by the is operator) unless they are "really" the same node. attribute, text, processing instruction and comment nodes all have simple content, that is, they have a string valued property (which is what you mean by CDATA above, although the term CDATA isn't used in XSL and means something slightly different in XML) element nodes and document nodes have complex content, so they do not have a string valued property (their string value is derived from the string value of their children) they do have other properties, notably properties listing the child and attribute nodes.

Andrew Welch adds

I think this is a good example:

<root>
 <foo>text</foo>
 <foo>text</foo>
</root>
<xsl:value-of select="/root"/>

produces "texttext" (with whitespace only nodes stripped)

This is because it's the string value of the <root> element - a sequence of length one.

<xsl:value-of select="/root/foo"/>

produces "text text"

This is because it's the string value of each <foo> element - a sequence of length two.

As there are two items in the sequence they are concatenated using the optional separator (the default being " ").