This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: XML/XQL/Tutorial,  Next: XML/XSLT,  Prev: XML/XQL/Query,  Up: Module List

Describes the XQL query syntax
******************************

NAME
====

   XML::XQL::Tutorial - Describes the XQL query syntax

DESCRIPTION
===========

   This document describes basic the features of the XML Query Language
(XQL.)  A proposal for the XML Query Language (XQL) specification was
submitted to the XSL Working Group in September 1998.  The spec can be
found at `http:' in this node.  Since it is only a proposal at this point,
things may change, but it is very likely that the final version will be
close to the proposal.  Most of this document was copied straight from the
spec.

   See also the *Note XML/XQL: XML/XQL, man page.

INTRODUCTION
============

   XQL (XML Query Language) provides a natural extension to the XSL pattern
language. It builds upon the capabilities XSL provides for identifying
classes of nodes, by adding Boolean logic, filters, indexing into
collections of nodes, and more.

   XQL is designed specifically for XML documents.  It is a general
purpose query language, providing a single syntax that can be used for
queries, addressing, and patterns.  XQL is concise, simple, and powerful.

   XQL is designed to be used in many contexts. Although it is a superset
of XSL patterns, it is also applicable to providing links to nodes, for
searching repositories, and for many other applications.

   Note that the term XQL is a working term for the language described in
this proposal. It is not their intent that this term be used permanently.
Also, beware that another query language exists called XML-QL, which uses
a syntax very similar to SQL.

   The *Note XML/XQL: XML/XQL, module has added functionality to the XQL
spec, called *XQL+*.  To allow only XQL functionality as described in the
spec, use the XML::XQL::Strict module. Note that the XQL spec makes the
distinction between core XQL and XQL extensions. This implementation makes
no distinction and the Strict module, therefore, implements everything
described in the XQL spec.  See the *Note XML/XQL: XML/XQL, man page for
more information about the Strict module.  This tutorial will clearly
indicate when referring to XQL+.

XQL Patterns
============

   This section describes the core XQL notation. These features should be
part of every XQL implementation, and serve as the base level of
functionality for its use in different technologies.

   The basic syntax for XQL mimics the URI directory navigation syntax, but
instead of specifying navigation through a physical file structure, the
navigation is through elements in the XML tree.

   For example, the following URI means find the foo.jpg file within the
bar directory:

     bar/foo.jpg

   Similarly, in XQL, the following means find the collection of fuz
elements within baz elements:

     baz/fuz

   Throughout this document you will find numerous samples. They refer to
the data shown in the sample file at the end of this man page.

Context
=======

   A context is the set of nodes against which a query operates.  For the
entire query, which is passed to the *Note XML/XQL/Query: XML/XQL/Query,
constructor through the Expr option, the context is the list of input nodes
that is passed to the query() method.

   XQL allows a query to select between using the current context as the
input context and using the 'root context' as the input context.  The
'root context' is a context containing only the root-most element of the
document. When using XML::DOM, this is the Document object.

   By default, a query uses the current context. A query prefixed with '/'
(forward slash) uses the root context. A query may optionally explicitly
state that it is using the current context by using the './' (dot, forward
slash) prefix. Both of these notations are analogous to the notations used
to navigate directories in a file system.

   The './' prefix is only required in one situation. A query may use the
'//' operator to indicate recursive descent. When this operator appears at
the beginning of the query, the initial '/' causes the recursive decent to
perform relative to the root of the document or repository. The prefix
'.//' allows a query to perform a recursive descent relative to the
current context.

Examples:
     Find all author elements within the current context. Since the period
     is really not used alone, this example forward-references other
     features:

          ./author

     Note that this is equivalent to:

          author

     Find the root element (bookstore) of this document:

          /bookstore

     Find all author elements anywhere within the current document:

          //author

     Find all books where the value of the style attribute on the book is
     equal to the value of the specialty attribute of the bookstore
     element at the root of the document:

          book[/bookstore/@specialty = @style]

Query Results
=============

   The collection returned by an XQL expression preserves document order,
hierarchy, and identity, to the extent that these are defined.  That is, a
collection of elements will always be returned in document order without
repeats. Note that the spec states that the order of attributes within an
element is undefined, but that this implementation does keep attributes in
document order. See the *Note XML/XQL: XML/XQL, man page for more details
regarding *Document Order*.

Collections - 'element' and '.'
===============================

   The collection of all elements with a certain tag name is expressed
using the tag name itself. This can be qualified by showing that the
elements are selected from the current context './', but the current
context is assumed and often need not be noted explicitly.

Examples:
     Find all first-name elements. These examples are equivalent:

          ./first-name

          first-name

     Find all unqualified book elements:

          book

     Find all first.name elements:

          first.name

Selecting children and descendants - '/' and '//'
=================================================

   The collection of elements of a certain type can be determined using
the path operators ('/' or '//'). These operators take as their arguments
a collection (left side) from which to query elements, and a collection
indicating which elements to select (right side). The child operator
('/')selects from immediate children of the left-side collection, while
the descendant operator ('//') selects from arbitrary descendants of the
left-side collection.  In effect, the '//' can be thought of as a
substitute for one or more levels of hierarchy. Note that the path
operators change the context as the query is performed. By stringing them
together users can 'drill down' into the document.

Examples:
     Find all first-name elements within an author element. Note that the
     author children of the current context are found, and then first-name
     children are found relative to the context of the author elements:

          author/first-name

     Find all title elements, one or more levels deep in the bookstore
     (arbitrary descendants):

          bookstore//title

     Note that this is different from the following query, which finds all
     title elements that are grandchildren of bookstore elements:

          bookstore/*/title

     Find emph elements anywhere inside book excerpts, anywhere inside the
     bookstore:

          bookstore//book/excerpt//emph

     Find all titles, one or more levels deep in the current context. Note
     that this situation is essentially the only one where the period
     notation is required:

          .//title

Collecting element children - '*'
=================================

   An element can be referenced without using its name by substituting the
'*' collection. The '*' collection returns all elements that are children
of the current context, regardless of their tag name.

Examples:
     Find all element children of author elements:

          author/*

     Find all last-names that are grand-children of books:

          book/*/last-name

     Find the grandchildren elements of the current context:

          */*

     Find all elements with specialty attributes. Note that this example
     uses subqueries, which are covered in Filters, and attributes, which
     are discussed in Finding an attribute:

          *[@specialty]

Finding an attribute - '@'
==========================

   Attribute names are preceded by the '@' symbol. XQL is designed to treat
attributes and sub-elements impartially, and capabilities are equivalent
between the two types wherever possible.

   Note: attributes cannot contain subelements. Thus, attributes cannot
have path operators applied to them in a query.  Such expressions will
result in a syntax error.  The XQL spec states that attributes are
inherently unordered and indices cannot be applied to them, but this
implementation allows it.

Examples:
     Find the style attribute of the current element context:

          @style

     Find the exchange attribute on price elements within the current
     context:

          price/@exchange

     The following example is not valid:

          price/@exchange/total

     Find all books with style attributes. Note that this example uses
     subqueries, which are covered in Filters:

          book[@style]

     Find the style attribute for all book elements:

          book/@style

XQL Literals
============

   XQL query expressions may contain literal values (i.e. constants.)
Numbers (integers and floats) are wrapped in XML::XQL::Number objects and
strings in XML::XQL::Text objects. Booleans (as returned by true() and
false()) are wrapped in XML::XQL::Boolean objects.

   Strings must be enclosed in single or double quotes. Since XQL does not
allow escaping of special characters, it's impossible to create a string
with both a single and a double quote in it. To remedy this, XQL+ has
added the q// and qq// string delimiters which behave just like they do in
Perl.

   For Numbers, exponential notation is not allowed. Use the XQL+ function
eval() to circumvent this problem. See *Note XML/XQL: XML/XQL, man page
for details.

   The empty list or undef is represented by [] (i.e. reference to empty
array) in this implementation.

Example
     Integer Numbers:

          234
          -456

     Floating point Numbers:

          1.23
          -0.99

     Strings:

          "some text with 'single' quotes"
          'text with "double" quotes'

     Not allowed:

          1.23E-4         (use eval("1.23E-4", "Number") in XQL+)

          "can't use \"double \"quotes"  (use q/can't use "double" quotes/ in XQL+)

Grouping - '()'
===============

   Parentheses can be used to group collection operators for clarity or
where the normal precedence is inadequate to express an operation.

Filters - '[]'
==============

   Constraints and branching can be applied to any collection by adding a
filter clause '[ ]' to the collection. The filter is analogous to the SQL
WHERE clause with ANY semantics. The filter contains a query within it,
called the subquery. The subquery evaluates to a Boolean, and is tested
for each element in the collection. Any elements in the collection failing
the subquery test are omitted from the result collection.

   For convenience, if a collection is placed within the filter, a Boolean
TRUE is generated if the collection contains any members, and a FALSE is
generated if the collection is empty. In essence, an expression such as
author/degree implies a collection-to-Boolean conversion function like the
following mythical 'there-exists-a' method.

     author[.there-exists-a(degree)]

   Note that any number of filters can appear at a given level of an
expression.  Empty filters are not allowed.

Examples:
     Find all books that contain at least one excerpt element:

          book[excerpt]

     Find all titles of books that contain at least one excerpt element:

          book[excerpt]/title

     Find all authors of books where the book contains at least one
     excerpt, and the author has at least one degree:

          book[excerpt]/author[degree]

     Find all books that have authors with at least one degree:

          book[author/degree]

     Find all books that have an excerpt and a title:

          book[excerpt][title]

Any and all semantics - '$any$' and '$all$'
-------------------------------------------

   Users can explicitly indicate whether to use any or all semantics
through the $any$ and $all$ keywords.

   $any$ flags that a condition will hold true if any item in a set meets
that condition. $all$ means that all elements in a set must meet the
condition for the condition to hold true.

   $any$ and $all$ are keywords that appear before a subquery expression
within a filter.

Examples:
     Find all author elements where one of the last names is Bob:

          author[last-name = 'Bob']

          author[$any$ last-name = 'Bob']

     Find all author elements where none of the last-name elements are Bob:

          author[$all$ last-name != 'Bob']

     Find all author elements where the first last name is Bob:

          author[last-name[0] = 'Bob']

Indexing into a collection - '[]' and '$to$'
============================================

   XQL makes it easy to find a specific node within a set of nodes.
Simply enclose the index ordinal within square brackets. The ordinal is 0
based.

   A range of elements can be returned. To do so, specify an expression
rather than a single value inside of the subscript operator (square
brackets).  Such expressions can be a comma separated list of any of the
following:

     n		Returns the nth element
     -n		Returns the element that is n-1 units from the last element.
     		E.g., -1 means the last element. -2 is the next to last element.
     m $to$ n	Returns elements m through n, inclusive

Examples:
     Find the first author element:

          author[0]

     Find the third author element that has a first-name:

          author[first-name][2]

     Note that indices are relative to the parent. In other words,
     consider the following data:

          <x>
            <y/>
            <y/>
          </x>
          <x>
            <y/>
            <y/>
          </x>

     The following expression will return the first y from each of the x's:

          x/y[0]

     The following will return the first y from the entire set of y's
     within x's:

          (x/y)[0]

     The following will return the first y from the first x:

          x[0]/y[0]

     Find the first and fourth author elements:

          author[0,3]

     Find the first through fourth author elements:

          author[0 $to$ 3]

     Find the first, the third through fifth, and the last author elements:

          author[0, 2 $to$ 4, -1]

     Find the last author element:

          author[-1]

Boolean Expressions
===================

   Boolean expressions can be used within subqueries. For example, one
could use Boolean expressions to find all nodes of a particular value, or
all nodes with nodes in particular ranges. Boolean expressions are of the
form ${op}$, where {op} may be any expression of the form {b|a} - that is,
the operator takes lvalue and rvalue arguments and returns a Boolean
result.

   Note that the XQL Extensions section defines additional Boolean
operations.

Boolean AND and OR - '$and$' and '$or$'
---------------------------------------

   $and$ and $or$ are used to perform Boolean ands and ors.

   The Boolean operators, in conjunction with grouping parentheses, can be
used to build very sophisticated logical expressions.

   Note that spaces are not significant and can be omitted, or included for
clarity as shown here.

Examples:
     Find all author elements that contain at least one degree and one
     award.

          author[degree $and$ award]

     Find all author elements that contain at least one degree or award
     and at least one publication.

          author[(degree $or$ award) $and$ publication]

Boolean NOT - '$not$'
---------------------

   $not$ is a Boolean operator that negates the value of an expression
within a subquery.

Examples:
     Find all author elements that contain at least one degree element and
     that contain no publication elements.

          author[degree $and$ $not$ publication]

     Find all author elements that contain publications elements but do
     not contain either degree elements or award elements.

          author[$not$ (degree $or$ award) $and$ publication]

Union and intersection - '$union$', '|' and '$intersect$'
=========================================================

   The $union$ operator (shortcut is '|') returns the combined set of
values from the query on the left and the query on the right. Duplicates
are filtered out.  The resulting list is sorted in document order.

   Note: because this is a union, the set returned may include 0 or more
elements of each element type in the list. To restrict the returned set to
nodes that contain at least one of each of the elements in the list, use a
filter, as discussed in Filters.

   The $intersect$ operator returns the set of elements in common between
two sets.

Examples:
     Find all first-names and last-names:

          first-name $union$ last-name

     Find all books and magazines from a bookstore:

          bookstore/(book | magazine)

     Find all books and all authors:

          book $union$ book/author

     Find the first-names, last-names, or degrees from authors within
     either books or magazines:

          (book $union$ magazine)/author/(first-name $union$ last-name $union$ degree)

     Find all books with author/first-name equal to 'Bob' and all
     magazines with price less than 10:

          book[author/first-name = 'Bob'] $union$ magazine[price $lt$ 10]

Equivalence - '$eq$', '=', '$ne$' and '!='
==========================================

   The '=' sign is used for equality; '!=' for inequality. Alternatively,
$eq$ and  $ne$ can be used for equality and inequality.

   Single or double quotes can be used for string delimiters in
expressions.  This makes it easier to construct and pass XQL from within
scripting languages.

   For comparing values of elements, the value() method is implied. That
is, last-name < 'foo' really means last-name!value() < 'foo'.

   Note that filters are always with respect to a context. That is, the
expression book[author] means for every book element that is found, see if
it has an author subelement. Likewise, book[author = 'Bob'] means for
every book element that is found, see if it has a subelement named author
whose value is 'Bob'. One can examine the value of the context as well, by
using the . (period). For example, book[. = 'Trenton'] means for every
book that is found, see if its value is 'Trenton'.

Examples:
     Find all author elements whose last name is Bob:

          author[last-name = 'Bob']

          author[last-name $eq$ 'Bob']

     Find all authors where the from attribute is not equal to 'Harvard':

          degree[@from != 'Harvard']

          degree[@from $ne$ 'Harvard']

     Find all authors where the last-name is the same as the
     /guest/last-name element:

          author[last-name = /guest/last-name]

     Find all authors whose text is 'Matthew Bob':

          author[. = 'Matthew Bob']

          author = 'Matthew Bob'

Comparison - '<', '<=', '>', '>=', '$lt', '$ilt$' etc.
------------------------------------------------------

   A set of binary comparison operators is available for comparing numbers
and strings and returning Boolean results.  $lt$, $le$, $gt$, $ge$ are
used for less than, less than or equal, greater than, or greater than or
equal. These same operators are also available in a case insensitive form:
$ieq$, $ine$, $ilt$, $ile$, $igt$, $ige$.

   <, <=, > and >= are allowed short cuts for $lt$, $le$, $gt$ and $ge$.

Examples:
     Find all author elements whose last name is bob and whose price is >
     50

          author[last-name = 'Bob' $and$ price $gt$ 50]

     Find all authors where the from attribute is not equal to 'Harvard':

          degree[@from != 'Harvard']

     Find all authors whose last name begins with 'M' or greater:

          author[last-name $ge$ 'M']

     Find all authors whose last name begins with 'M', 'm' or greater:

          author[last-name $ige$ 'M']

     Find the first three books:

          book[index() $le$ 2]

     Find all authors who have more than 10 publications:

          author[publications!count() $gt$ 10]

XQL+ Match operators - '$match$', '$no_match$', '=~' and '!~'
-------------------------------------------------------------

   XQL+ defines additional operators for pattern matching. The $match$
operator (shortcut is '=~') returns TRUE if the lvalue matches the pattern
described by the rvalue. The $no_match$ operator (shortcut is '!~')
returns FALSE if they match. Both lvalue and rvalue are first cast to
strings.

   The rvalue string should have the syntax of a Perl rvalue, that is the
delimiters should be included and modifiers are allowed. When using
delimiters other than slashes '/', the 'm' should be included. The rvalue
should be a string, so don't forget the quotes! (Or use the q// or qq//
delimiters in XQL+, see *Note XML/XQL: XML/XQL, man page.)

   Note that you can't use the Perl substitution operator s/// here. Try
using the XQL+ subst() function instead.

Examples:
     Find all authors whose name contains bob or Bob:

          author[first-name =~ '/[Bb]ob/']

     Find all book titles that don't contain 'Trenton' (case-insensitive):

          book[title !~ 'm!trenton!i']

Oher XQL+ comparison operators - '$isa', '$can$'
------------------------------------------------

   See the *Note XML/XQL: XML/XQL, man page for other operators available
in XQL+.

Comparisons and vectors
-----------------------

   The lvalue of a comparison can be a vector or a scalar. The rvalue of a
comparison must be a scalar or a value that can be cast at runtime to a
scalar.

   If the lvalue of a comparison is a set, then any (exists) semantics are
used for the comparison operators. That is, the result of a comparison is
true if any item in the set meets the condition.

Comparisons and literals
------------------------

   The spec states that the lvalue of an expression cannot be a literal.
That is, *'1' = a* is not allowed. This implementation allows it, but it's
not clear how useful that is.

Casting of literals during comparison
-------------------------------------

   Elements, attributes and other XML node types are casted to strings
(Text) by applying the value() method. The value() method calls the text()
method by default, but this behavior can be altered by the user, so the
value() method may return other XQL data types.

   When two values are compared, they are first casted to the same type.
See the *Note XML/XQL: XML/XQL, man page for details on casting.

   Note that the XQL spec is not very clear on how values should be casted
for comparison. Discussions with the authors of the XQL spec revealed that
there was some disagreement and their implementations differed on this
point.  This implementation is closest to that of Joe Lapp from
webMethods, Inc.

Methods - 'method()' or 'query!method()'
========================================

   XQL makes a distinction between functions and methods.  See the *Note
XML/XQL: XML/XQL, man page for details.

   XQL provides methods for advanced manipulation of collections. These
methods provide specialized collections of nodes (see Collection methods),
as well as information about sets and nodes.

   Methods are of the form *method(arglist)*

   Consider the query book[author]. It will find all books that have
authors.  Formally, we call the book corresponding to a particular author
the reference node for that author. That is, every author element that is
examined is an author for one of the book elements. (See the Annotated XQL
BNF Appendix for a much more thorough definition of reference node and
other terms. See also the XML::XQL man page.) Methods always apply to the
reference node.

   For example, the text() method returns the text contained within a node,
minus any structure. (That is, it is the concatenation of all text nodes
contained with an element and its descendants.) The following expression
will return all authors named 'Bob':

     author[text() = 'Bob']

   The following will return all authors containing a first-name child
whose text is 'Bob':

     author[first-name!text() = 'Bob']

   The following will return all authors containing a child named Bob:

     author[*!text() = 'Bob']

   Method names are case sensitive.  See the *Note XML/XQL: XML/XQL, man
page on how to define your own methods and functions.

Information methods
-------------------

   The following methods provide information about nodes in a collection.
These methods return strings or numbers, and may be used in conjunction
with comparison operators within subqueries.

Method: text()
     The text() method concatenates text of the descendents of a node,
     normalizing white space along the way. White space will be preserved
     for a node if the node has the xml:space attribute set to 'preserve',
     or if the nearest ancestor with the xml:space attribute has the
     attribute set to 'preserve'. When white space is normalized, it is
     normalized across the entire string. Spaces are used to separate the
     text between nodes.  When entity references are used in a document,
     spacing is not inserted around the entity refs when they are expanded.

     In this implementation, the method may receive an optional parameter
     to indicate whether the text() of Element nodes should include the
     text() of its Element descendants. See *Note XML/XQL: XML/XQL, man
     page for details.

     Examples:

     Find the authors whose last name is 'Bob':

          author[last-name!text() = 'Bob']

     Note this is equivalent to:

          author[last-name = 'Bob']

     Find the authors with value 'Matthew Bob':

          author[text() = 'Matthew Bob']

          author[. = 'Matthew Bob']

          author = 'Matthew Bob'

Method: rawText()
     The rawText() method is similar to the text() method, but it does not
     normalize whitespace.

     In this implementation, the method may receive an optional parameter
     to indicate whether the rawText() of Element nodes should include the
     rawText() of its Element descendants. See *Note XML/XQL: XML/XQL, man
     page for details.

Method: value()
     Returns a type cast version of the value of a node. If no data type is
     provided, returns the same as text().

    Shortcuts
          For the purposes of comparison, value( )is implied if omitted.
          In other words, when two items are compared, the comparison is
          between the value of the two items. Remember that in absence of
          type information, value() returns text().

          The following examples are equivalent:

               author[last-name!value() = 'Bob' $and$ first-name!value() = 'Joe']

               author[last-name = 'Bob' $and$ first-name = 'Joe']

               price[@intl!value() = 'canada']

               price[@intl = 'canada']

Method: nodeType()
     Returns a number to indicate the type of the node. The values were
     based on the node type values in the DOM:

          element		1
          attribute	2
          text		3
          entity		6	(not in XQL spec)
          PI		7
          comment		8
          document	9
          doc. fragment	10	(not in XQL spec)
          notation	11	(not in XQL spec)

     Note that in XQL, CDATASection nodes and EntityReference nodes also
     return 3, whereas in the DOM CDATASection returns 4 and
     EntityReference returns 5.  Use the XQL+ method DOM_nodeType() to get
     DOM node type values.  See the *Note XML/DOM: XML/DOM, man page for
     node type values of nodes not mentioned here.

Method: nodeTypeString
     Returns the name of the node type in lowercase or an empty string. The
     following node types are currently supported 1 (element), 2
     (attribute), 3 (text), 7 (processing_instruction), 8 (comment), 9
     (document)

Method: nodeName()
     Returns the tag name for Element nodes and the attribute name of
     attributes.

Collection index methods
------------------------

Method: index()
     Returns the index of the value within the search context (i.e. with
     the input list of the subquery.) This is not necessarily the same as
     the index of a node within its parent node. Note that the XQL spec
     doesn't explain it well.

    Examples:
          Find the first 3 degrees:

               degree[index() $lt$ 3]

          Note that it skips over other nodes that may exist between the
          degree elements.

          Consider the following data:

               <x>
                 <y/>
                 <y/>
               </x>
               <x>
                 <y/>
                 <y/>
               </x>

          The following expression will return the first y from each x:

               x/y[index() = 0]

          This could also be accomplished by (see Indexing into a
          Collection):

               x/y[0]

Method: end()
     The end() method returns true for the last element in the search
     context.  Again, the XQL spec does not explain it well.

    Examples:
          Find the last book:

               book[end()]

          Find the last author for each book:

               book/author[end()]

          Find the last author from the entire set of authors of books:

               (book/author)[end()]

Aggregate methods
-----------------

Method: count( [QUERY] )
     Returns the number of values inside the search context.  In XQL+,
     when the optional QUERY parameter is supplied, it returns the number
     of values returned by the QUERY.

Namespace methods
-----------------

   The following methods can be applied to a node to return namespace
information.

Method: baseName()
     Returns the local name portion of the node, excluding the prefix.
     Local names are defined only for element nodes and attribute nodes.
     The local name of an element node is the local portion of the node's
     element type name. The local name of an attribute node is the local
     portion of the node's attribute name. If a local name is not defined
     for the reference node, the method evaluates to the empty set.

Method: namespace()
     Returns the URI for the namespace of the node.  Namespace URIs are
     defined only for element nodes and attribute nodes.  The namespace
     URI of an element node is the namespace URI associated with the
     node's element type name. The namespace URI of an attribute node is
     the namespace URI associated with the node's attribute name. If a
     namespace URI is not defined for the reference node, the method
     evaluates to the empty set.

Method: prefix()
     Returns the prefix for the node. Namespace prefixes are defined only
     for element nodes and attribute nodes. The namespace prefix of an
     element node is the shortname for the namespace of the node's element
     type name.  The namespace prefix of an attribute node is the
     shortname for the namespace of the node's attribute name.  If a
     namespace prefix is not defined for the reference node, the method
     evaluates to the empty set.

     The spec states: A node's namespace prefix may be defined within the
     query expression, within the document under query, or within both the
     query expression and the document under query. If it is defined in
     both places the prefixes may not agree. In this case, the prefix
     assigned by the query expression takes precedence.  In this
     implementation you cannot define the namespace for a query, so this
     can never happen.

    Examples:
          Find all unqualified book elements. Note that this does not
          return my:book elements:

               book

          Find all book elements with the prefix 'my'. Note that this
          query does not return unqualified book elements:

               my:book

          Find all book elements with a 'my' prefix that have an author
          subelement:

               my:book[author]

          Find all book elements with a 'my' prefix that have an author
          subelement with a my prefix:

               my:book[my:author]

          Find all elements with a prefix of 'my':

               my:*

          Find all book elements from any namespace:

               *:book

          Find any element from any namespace:

               *

          Find the style attribute with a 'my' prefix within a book
          element:

               book/@my:style

     All attributes of an element can be returned using @*.  This is
     potentially useful for applications that treat attributes as fields
     in a record.

    Examples:
          Find all attributes of the current element context:

               @*

          Find style attributes from any namespace:

               @*:style

          Find all attributes from the 'my' namespace, including
          unqualified attributes on elements from the 'my' namespace:

               @my:*

Functions
=========

   This section defines the functions of XQL. The spec states that: XQL
defines two kinds of functions: collection functions and pure functions.
Collection functions use the search context of the Invocation instance,
while pure functions ignore the search context, except to evaluate the
function's parameters. A collection function evaluates to a subset of the
search context, and a pure function evaluates to either a constant value
or to a value that depends only on the function's parameters.

   Don't worry if you don't get it. Just use them!

Collection functions
--------------------

   The collection functions provide access to the various types of nodes
in a document. Any of these collections can be constrained and indexed.
The collections return the set of children of the reference node meeting
the particular restriction.

Function: textNode()                   The collection of text nodes.
Function: comment()
     The collection of comment nodes.

Function: pi()
     The collection of processing instruction nodes.

Function: element( [NAME] )
     The collection of all element nodes. If the optional text parameter
     is provided, it only returns element children matching that
     particular name.

Function: attribute( [NAME] )
     The collection of all attribute nodes. If the optional text parameter
     is provided, it only returns attributes matching that particular name.

Function: node()
     The collection of all non-attribute nodes.

    Examples:
          Find the second text node in each p element in the current
          context:

               p/textNode()[1]

          Find the second comment anywhere in the document. See Context
          for details on setting the context to the document root:

               //comment()[1]

Other XQL Functions
-------------------

Function: ancestor(QUERY)
     Finds the nearest ancestor matching the provided query. It returns
     either a single element result or an empty set [].  Note that this
     node is never the reference node itself.

    Examples:
          Find the nearest book ancestor of the current element:

               ancestor(book)

          Find the nearest ancestor author element that is contained in a
          book element:

               ancestor(book/author)

Function: id(NAME)
     Pure function that evaluates to a set. The set contains an element
     node that has an 'id' attribute whose value is identical to the
     string that the Text parameter quotes. The element node may appear
     anywhere within the document under query. If more than one element
     node meets these criteria, the function evaluates to a set that
     contains the first node appearing in a document ordering of the nodes.

Function: true() and false()
     Pure functions that each evaluate to a Boolean. "true()" evaluates to
     'true', and "false()" evaluates to 'false'. These functions are
     useful in expressions that are constructed using entity references or
     variable substitution, since they may replace an expression found in
     an instance of Subquery without violating the syntax required by the
     instance of Subquery.  They return an object of type
     XML::XQL::Boolean.

Function: date(QUERY)
     "date" is a pure function that typecasts the value of its parameter
     to a set of dates. If the parameter matches a single string, the
     value of the function is a set containing a single date. If the
     parameter matches a QUERY, the value of the function is a set of
     dates, where the set contains one date for each member of the set to
     which the parameter evaluates.

     XQL does not define the representation of the date value, nor does it
     define how the function translates parameter values into dates.  This
     implementation uses the Date::Manip module to parse dates, which
     accepts almost any imaginable format. See *Note XML/XQL: XML/XQL, to
     plug in your own Date implementation.

     Include the *Note XML/XQL/Date: XML/XQL/Date, package to add the XQL
     date type and the date() function, like this:

          use XML::XQL::Date;

Perl builtin functions and other XQL+ functions
     XQL+ provides XQL function wrappers for most Perl builtin functions.
     It also provides other cool functions like subst(), map(), and eval()
     that allow you to modify documents and embed perl code.  If this is
     still not enough, you can add your own function and methods.  See
     *Note XML/XQL: XML/XQL, man page for details.

Sequence Operators - ';' and ';;'
=================================

   The whitepaper 'The Design of XQL' by Jonathan Robie, which can be found
at `http:' in this node describes the sequence operators ';;' (precedes)
and ';' (immediately precedes.) Although these operators are not included
in the XQL spec, I thought I'd add them anyway.

Immediately Precedes - ';'
--------------------------

Example:
     With the following input:

          <TABLE>
           <ROWS>
            <TR>
             <TD>Shady Grove</TD>
             <TD>Aeolian</TD>
            </TR>
            <TR>
             <TD>Over the River, Charlie</TD>
             <TD>Dorian</TD>
            </TR>
           </ROWS>
          </TABLE>

     Find the TD node that contains "Shady Grove" and the TD node that
     immediately follows it:

          //(TD="Shady Grove" ; TD)

   Note that in XML::DOM there is actually a text node with whitespace
between the two TD nodes, but those are ignored by this operator, unless
the text node has 'xml:space' set to 'preserve'. See ??? for details.

Precedes - ';;'
---------------

Example:
     With the following input (from Hamlet):

          <SPEECH>
           <SPEAKER>MARCELLUS</SPEAKER>
           <LINE>Tis gone!</LINE>
           <STAGEDIR>Exit Ghost</STAGEDIR>
           <LINE>We do it wrong, being so majestical,</LINE>
           <LINE>To offer it the show of violence;</LINE>
           <LINE>For it is, as the air, invulnerable,</LINE>
           <LINE>And our vain blows malicious mockery.</LINE>
          </SPEECH>

     Return the STAGEDIR and all the LINEs that follow it:

          SPEECH//( STAGEDIR ;; LINE )

     Suppose an actor playing the ghost wants to know when to exit; that
     is, he wants to know who says what line just before he is supposed to
     exit. The line immediately precedes the stagedir, but the speaker may
     occur at any time before the line.  In this query, we will use the
     "precedes" operator (";;") to identify a speaker that precedes the
     line somewhere within a speech. Our ghost can find the required
     information with the following query, which selects the speaker, the
     line, and the stagedir:

          SPEECH//( SPEAKER ;; LINE ; STAGEDIR="Exit Ghost")

Operator Precedence
===================

   The following table lists operators in precedence order, highest
precedence first, where operators of a given row have the same precedence.
The table also lists the associated productions:

     Production	Operator(s)
     ----------	-----------
     Grouping	( )
     Filter		[ ]
     Subscript	[ ]
     Bang		!
     Path		/ //
     Match		$match$ $no_match$ =~ !~ (XQL+ only)
     Comparison	= != < <= > >= $eq$ $ne$ $lt$ $le$ $gt$
     		$ge$ $ieq$ $ine$ $ilt$ $ile$ $igt$ $ige$
     Intersection	$intersect$
     Union		$union$ |
     Negation	$not$
     Conjunction	$and$
     Disjunction	$or$
     Sequence	; ;;

Sample XML Document - bookstore.xml
===================================

   This file is also stored in samples/bookstore.xml that comes with the
XML::XQL distribution.

     <?xml version='1.0'?>
     <!-- This file represents a fragment of a book store inventory database -->
     <bookstore specialty='novel'>
       <book style='autobiography'>
         <title>Seven Years in Trenton</title>
         <author>
           <first-name>Joe</first-name>
           <last-name>Bob</last-name>
           <award>Trenton Literary Review Honorable Mention</award>
         </author>
         <price>12</price>
       </book>
       <book style='textbook'>
         <title>History of Trenton</title>
         <author>
           <first-name>Mary</first-name>
           <last-name>Bob</last-name>
           <publication>
             Selected Short Stories of
             <first-name>Mary</first-name> <last-name>Bob</last-name>
           </publication>
         </author>
         <price>55</price>
       </book>
       <magazine style='glossy' frequency='monthly'>
         <title>Tracking Trenton</title>
         <price>2.50</price>
         <subscription price='24' per='year'/>
       </magazine>
       <book style='novel' id='myfave'>
         <title>Trenton Today, Trenton Tomorrow</title>
         <author>
           <first-name>Toni</first-name>
           <last-name>Bob</last-name>
           <degree from='Trenton U'>B.A.</degree>
           <degree from='Harvard'>Ph.D.</degree>
           <award>Pulizer</award>
           <publication>Still in Trenton</publication>
           <publication>Trenton Forever</publication>
         </author>
         <price intl='canada' exchange='0.7'>6.50</price>
         <excerpt>
           <p>It was a dark and stormy night.</p>
           <p>But then all nights in Trenton seem dark and
           stormy to someone who has gone through what
           <emph>I</emph> have.</p>
           <definition-list>
             <term>Trenton</term>
             <definition>misery</definition>
           </definition-list>
         </excerpt>
       </book>
       <my:book style='leather' price='29.50' xmlns:my='http://www.placeholder-name-here.com/schema/'>
         <my:title>Who's Who in Trenton</my:title>
         <my:author>Robert Bob</my:author>
       </my:book>
     </bookstore>

SEE ALSO
========

   The Japanese version of this document can be found on-line at `http:'
in this node

   *Note XML/XQL: XML/XQL,, *Note XML/XQL/Date: XML/XQL/Date,, *Note
XML/XQL/Query: XML/XQL/Query, and *Note XML/XQL/DOM: XML/XQL/DOM,


File: pm.info,  Node: XML/XSLT,  Next: XML/miniXQL,  Prev: XML/XQL/Tutorial,  Up: Module List

A perl module for processing XSLT
*********************************

NAME
====

   XML::XSLT - A perl module for processing XSLT

   __my_tag_compression__( $tag, $elem )

   A function for DOM::XML::setTagCompression to determine the style for
printing of empty tags and empty container tags.

   XML::XSLT implements an XHTML-friendly style.

   Allow tag to be preceded by a namespace: ([\w\.]+\:){0,1}

     <br> -> <br />

     or

     <myns:hr> -> <myns:hr />

   Empty tag list obtained from:

     http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd

   According to "Appendix C. HTML Compatibility Guidelines",   C.3 Element
Minimization and Empty Element Content

     Given an empty instance of an element whose content model is not EMPTY
     (for example, an empty title or paragraph) do not use the minimized form
     (e.g. use <p> </p> and not <p />).

   However, the <p> tag is processed like an empty tag here!

   Tags allowed:

     base meta link hr br param img area input col

   Special Case: p (even though it violates C.3)

   The tags are matched in order of expected common occurence.

SYNOPSIS
========

     use XML::XSLT;

     my $xslt = XML::XSLT->new ($xsl, warnings => 1);

     $xslt->transform ($xmlfile)
     print $xslt->asString

     $xslt->dispose ();

DESCRIPTION
===========

   This module implements the W3C's XSLT specification. The goal is full
implementation of this spec, but we have not yet achieved that. However,
it already works well.  See `XML::XSLT Commands' in this node for the
current status of each command.

   XML::XSLT makes use of XML::DOM and LWP::Simple, while XML::DOM uses
XML::Parser.  Therefore XML::Parser, XML::DOM and LWP::Simple have to be
installed properly for XML::XSLT to run.

Specifying Sources
==================

   The stylesheets and the documents may be passed as filenames, file
handles regular strings, string references or DOM-trees.  Functions that
require sources (e.g. new), will accept either a named parameter or simply
the argument.

   Either of the following are allowed:

     my $xslt = XML::XSLT->new($xsl);
     my $xslt = XML::XSLT->new(Source => $xsl);

   In documentation, the named parameter `Source' is always shown, but it
is never required.

METHODS
=======

new(Source => $xml [, %args])
-----------------------------

   Returns a new XSLT parser object.  Valid flags are:

DOMparser_args
     Hashref of arguments to pass to the XML::DOM::Parser object's parse
     method.

variables
     Hashref of variables and their values for the stylesheet.

base
     Base of URL for file inclusion.

debug
     Turn on debugging messages.

warnings
     Turn on warning messages.

indent
     Starting amount of indention for debug messages.  Defaults to 0.

indent_incr
     Amount to indent each level of debug message.  Defaults to 1.

open_xml(Source => $xml [, %args])
----------------------------------

   Gives the XSLT object new XML to process.  Returns an XML::DOM object
corresponding to the XML.

base
     The base URL to use for opening documents.

parser_args
     Arguments to pase to the parser.

open_xsl(Source => $xml, [, %args])
-----------------------------------

   Gives the XSLT object a new stylesheet to use in processing XML.
Returns an XML::DOM object corresponding to the stylesheet.  Any arguments
present are passed to the XML::DOM::Parser.

base
     The base URL to use for opening documents.

parser_args
     Arguments to pase to the parser.

process(%variables)
-------------------

   Processes the previously loaded XML through the stylesheet using the
variables set in the argument.

transform(Source => $xml [, %args])
-----------------------------------

   Processes the given XML through the stylesheet.  Returns an XML::DOM
object corresponding to the transformed XML.  Any arguments present are
passed to the XML::DOM::Parser.

serve(Source => $xml [, %args])
-------------------------------

   Processes the given XML through the stylesheet.  Returns a string
containg the result.  Example:

     use XML::XSLT qw(serve);

     $xslt = XML::XSLT->new($xsl);
     print $xslt->serve $xml;

http_headers
     If true, then prepends the appropriate HTTP headers (e.g.
     Content-Type, Content-Length);

     Defaults to true.

xml_declaration
     If true, then the result contains the appropriate <?xml?> header.

     Defaults to true.

xml_version
     The version of the XML.

     Defaults to 1.0.

doctype
     The type of DOCTYPE this document is.  Defaults to SYSTEM.

toString
--------

   Returns the result of transforming the XML with the stylesheet as a
string.

to_dom
------

   Returns the result of transforming the XML with the stylesheet as an
XML::DOM object.

media_type
----------

   Returns the media type (aka mime type) of the object.

dispose
-------

   Executes the dispose method on each XML::DOM object.

XML::XSLT Commands
==================

xsl:apply-imports		no
---------------------

   Not supported yet.

xsl:apply-templates		limited
----------------------------

   Attribute 'select' is supported to the same extent as xsl:value-of
supports path selections.

   Not supported yet: - attribute 'mode' - xsl:sort and xsl:with-param in
content

xsl:attribute			partially
-------------------------

   Adds an attribute named to the value of the attribute 'name' and as
value the stringified content-template.

   Not supported yet: - attribute 'namespace'

xsl:attribute-set		no
---------------------

   Not supported yet.

xsl:call-template		yes
----------------------

   Takes attribute 'name' which selects xsl:template's by name.

   Weak support: - xsl:with-param (select attrib not supported)

   Not supported yet: - xsl:sort

xsl:choose			yes
----------------

   Tests sequentially all xsl:whens until one succeeds or until an
xsl:otherwise is found. Limited test support, see xsl:when

xsl:comment			yes
-----------------

   Supported.

xsl:copy				partially
---------------------

   Not supported yet: - attribute 'use-attribute-sets'

xsl:copy-of			limited
---------------------

   Attribute 'select' functions as well as with xsl:value-of

xsl:decimal-format		no
----------------------

   Not supported yet.

xsl:element			yes
-----------------

xsl:fallback			no
-----------------

   Not supported yet.

xsl:for-each			limited
----------------------

   Attribute 'select' functions as well as with xsl:value-of

   Not supported yet: - xsl:sort in content

xsl:if				limited
-----------------

   Identical to xsl:when, but outside xsl:choose context.

xsl:import			no
---------------

   Not supported yet.

xsl:include			yes
-----------------

   Takes attribute href, which can be relative-local, absolute-local as
well as an URL (preceded by identifier http:).

xsl:key				no
-------------

   Not supported yet.

xsl:message			no
----------------

   Not supported yet.

xsl:namespace-alias		no
-----------------------

   Not supported yet.

xsl:number			no
---------------

   Not supported yet.

xsl:otherwise			yes
-------------------

   Supported.

xsl:output			limited
--------------------

   Only the initial xsl:output element is used.  The "text" output method
is not supported, but shouldn't be difficult to implement.  Only the
"doctype-public", "doctype-system", "omit-xml-declaration", "method", and
"encoding" attributes have any support.

xsl:param			experimental
------------------------

   Synonym for xsl:variable (currently). See xsl:variable for support.

xsl:preserve-space		no
----------------------

   Not supported yet. Whitespace is always preserved.

xsl:processing-instruction	yes
------------------------------

   Supported.

xsl:sort				no
--------------

   Not supported yet.

xsl:strip-space			no
--------------------

   Not supported yet. No whitespace is stripped.

xsl:stylesheet			limited
------------------------

   Minor namespace support: other namespace than 'xsl:' for xsl-commands
is allowed if xmlns-attribute is present. xmlns URL is verified.  Other
attributes are ignored.

xsl:template			limited
----------------------

   Attribute 'name' and 'match' are supported to minor extend.  ('name'
must match exactly and 'match' must match with full path or no path)

   Not supported yet: - attributes 'priority' and 'mode'

xsl:text				yes
---------------

   Supported.

xsl:transform			limited
-----------------------

   Synonym for xsl:stylesheet

xsl:value-of			limited
----------------------

   Inserts attribute or element values. Limited support:

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

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

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

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

   <xsl:value-of select="elem[n]"/>

   <xsl:value-of select="//elem[n]"/>

   <xsl:value-of select="@attr"/>

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

   <xsl:value-of select="processing-instruction()"/>

   <xsl:value-of select="comment()"/>

   and combinations of these.

   Not supported yet: - attribute 'disable-output-escaping'

xsl:variable			experimental
---------------------------

   Very limited. It should be possible to define a variable and use it with
&lt;xsl:value select="$varname" /&gt; within the same template.

xsl:when				limited
-------------------

   Only inside xsl:choose. Limited test support:

   <xsl:when test="@attr='value'">

   <xsl:when test="elem='value'">

   <xsl:when test="path/[@attr='value']">

   <xsl:when test="path/[elem='value']">

   <xsl:when test="path">

   path is supported to the same extend as with xsl:value-of

xsl:with-param			experimental
-----------------------------

   It is currently not functioning. (or is it?)

SUPPORT
=======

   General information, bug reporting tools, the latest version, mailing
lists, etc. can be found at the XML::XSLT homepage:

     http://xmlxslt.sourceforge.net/

DEPRECATIONS
============

   Methods and interfaces from previous versions that are not documented
in this version are deprecated.  Each of these deprecations can still be
used but will produce a warning when the deprecation is first used.  You
can use the old interfaces without warnings by passing new() the flag
`use_deprecated'.  Example:

     $parser = XML::XSLT->new($xsl, "FILE",
                              use_deprecated => 1);

   The deprecations will disappear by the time a 1.0 release is made.

BUGS
====

   Yes.

HISTORY
=======

   Geert Josten and Egon Willighagen developed and maintained XML::XSLT up
to version 0.22.  At that point, Mark Hershberger started moving the
project to Sourceforge and began working on it with Bron Gondwana.

LICENCE
=======

   Copyright (c) 1999 Geert Josten & Egon Willighagen. All Rights
Reserverd.  This module is free software, and may be distributed under the
same terms and conditions as Perl.

AUTHORS
=======

   Geert Josten <gjosten@sci.kun.nl>, Egon Willighagen <egonw@sci.kun.nl>,
Mark A. Hershberger <mah@everybody.org> Bron Gondwana <perlcode@brong.net>,

SEE ALSO
========

   *Note XML/DOM: XML/DOM,, *Note LWP/Simple: LWP/Simple,, *Note
XML/Parser: XML/Parser,


