In XSH2, like in Perl and XPath, 
	variable names are are prefixed
        with a dollar sign ($). 
        Variables can
        contain arbitrary Perl Scalar (string, number, array
        reference, hash reference or an object reference).  XPath
        objects are transparently mapped to Perl objects via
        XML::LibXML objects. 
        Values can be assigned to variables
        either by simple assignments of the form
	$variable = expression,
        where the right hand side is an expression, or by command 
        assignments of the form
	$variable := command,
        where the right hand side is a XSH2 command, or by
	capturing the output of some command with a variable
	redirection of the following form:
command |> $variable;
	XSH2 expressions are evaluated either by XPath
	engine or by Perl (the latter only happens if the entire
	expression is enclosed with braces
	{...}), and
	both Perl and XPath can access all XSH2 variables
	transparently (Perl expressions may even assign to them).
      
	A simple simple expression consisting of a variable name
        (e.g. $variable) is always evaluated by the
        XPath engine and the result is the content of the variable as
        it appears to the XPath data model.  Since in XPath object
        cannot be void (undefined), XPath engine complains, if the
        value of the variable is undefined. On the other hand,
        expressions like {$variable} are evaluated by
        Perl, which results in the value of the variable as seen
	by Perl.
      
	Variables can also be used as macros for complicated XPath
	expressions. Any occurrence of a substring of the form
	${variable} in an XPath expression is
	interpolated to the value of $variable (if
	$variable contains an object rather than a
	string or number, then the object is cast to string first) before the
	entire expression is evaluated.  So, for example, if
	${variable} contains string
	"chapter[title]" (without the quotes), then
	the XPath expression
	//sect1/${variable}/para interpolates to 
	//sect1/chapter[title]/para prior
	to evaluation. 
      
To display the current value of a variable, use either print or (in case of a global variables - the distinction is discussed below) the command variables:
Example 1.
xsh>$b="my_document";xsh>$file="${b}s.xml";xsh>$f := open $file;xsh>ls //$b[count(descendant::para)>10]xsh>print $bmy_document xsh>variables... $b='my_document'; ... $file='my_documents.xml'; ...
	Variables can also serve as containers for documents and can be used to
	store lists of nodes that result from evaluating an XPath
	expression (a.k.a. XPath node-sets). This is especially useful
	when a sequence of commands is to be performed on some fixed
        set of nodes and repetitive evaluation of the same XPath 
	expression would be lengthy.  XPath
	node-sets are represented by
	XML::LibXML::NodeList Perl objects (which
	is simply a array reference blessed to the above class, which
	provides some simple operator overloading). In XPath, by a
	node-set by definition can only contain a single copy of each
	node and the nodes within a node-set are processed in the same
	order as they appear in the XML document. Having XPath
	node-sets represented by a list gives us the advantage of having
	the possibility to process the list in a different order than
	the one implied by the document (which is what happens
	if a variable containing a node-list is evaluated by Perl 
	rather than XPath), see an example below.
      
Example 2.
xsh>$creatures = //creature[@status='alive']# process creatures in the document order: xsh>foreach $creature print @name;# process creatures in the reverse document order: xsh>foreach { reverse @$creature } print @name;# append some more nodes to a node-list (using a variant of # a simple assignment) xsh>$creatures += //creature[@status='dead'];# again, we can process creatures in order implied by the document: xsh>foreach $creature print @name;# but we can also process first living and then dead creatures, # since this is how they are listed in $creature xsh>foreach {$creature} print @name;# same as the above is xsh>foreach {@$creature} print @name;
XSH2 variables are either globally or lexically scoped. Global variables need not to be declared (they can be directly assigned to), whereas lexical variables must be declared using the command my. Global variable assignment may also be made temporal for the enclosing block, using local.
Example 3.
$var1 = "foo"; # a global variable requires no declaration local $var1 $var2 $var3; # localizes global variables $var1 = "bar"; # assignment to a localized variable is temporary local $var4 = "foo"; # localized assignment my $var1 $var $var3; # declares lexical variables my $var1 = "foo"; # lexical variable declaration with assignment
Lexical variables are only defined in the scope of current block or subroutine. There is no way to refer to a lexical variable form outside of the block it was declared in, nor from within a nested subroutine call. Of course, lexical variables can be referred to from nested blocks or Perl expressions (where they behave just like Perl's lexical variables).
	On the other hand, global or localized XSH2 variables are just
	Perl Scalar variables belonging to the
	XML::XSH2::Map namespace, which is also the
	default namespace for any Perl code evaluated from XSH2 (so
	there's no need to use this prefix explicitly in Perl expressions,
	unless of course there is a lexical variable in the current
	scope with the same).
      
Localizing a variable using the local
	keyword makes all assignments to it occurring in the enclosing block
	temporary. The variable itself remains global, only its
	original value is restored at the end of the block that localized it.
      
In all above cases, it is possible to arbitrarily intermix XSH2 and Perl assignments:
Example 4.
xsh>ls //chapter[1]/title<title>Introduction</title> xsh>$a=string(//chapter[1]/title)xsh>perl { $b="CHAPTER 1: ".uc($a); }xsh>print $bCHAPTER 1: INTRODUCTION
Although all XSH2 variables are in fact Perl Scalars, it is still possible to store Perl Array or Hash value to a XSH2 variable via reference. The following example demonstrates using Perl Hashes to collect and print some simple racial statistics about the population of Middle-Earth:
Example 5.
my $races;
foreach a:/middle-earth/creature { 
  my $race=string(@race);
  perl { $races->{$race}++ };
}
print "Middle-Earth Population (race/number of creatures)"
print { map "$_/$races->{$_}\n" keys(%$races); };