Using XPath queries to XML views tutorial
Genaral Using XPath queries to XML views. Overview.

## XPATH Implementation and SQL

Virtuoso offers XPATH as a query language for XML views. The statement is there converted into SQL in the context of the mapping defined by the __view XPATH option, which is mandatory. An XPATH query string is a valid top level SQL statement. This is interpreted as a single select or union of selects with the result columns being specified by various XPATH options. The basic query string

    XPATH [__view "xmlview_name"] /xpath_query

The same functionality can be got by the following query:

    select * from (XPATH '[__view "xmlview_name"]/xpath_query')n

Xml view can be created by two methods:

- using CREATE XML VIEW statement
- using Annotated XSD Schemas

The second method is described in 'Using Annotated XSD Schemas for Creating XML View' chapter of this tutorial.

## CREATE XML VIEW statement

The XML view declaration establishes a 'virtual document' a context within which XML hierarchy relationships can be translated into arbitrary joins. The virtual document can be then materialized into an actual set of persistent XML elements or used to generate SQL from XPATH. The XML view declaration corresponds to the grammar rules described in XML Support chapter, Virtuoso XML Services section.

Each table in the declaration generates an element into the result document. SQL views can be used as tables to accommodate for hidden joins, sub-queries, ordering and aggregates. If a view is used, which by nature has no primary key, the primary key clause should be used to define a uniquely identifying set of view columns.

Each level of the hierarchy is declared as a list of child elements. Each such element maps one table or view into an entity according to a join condition. The join conditions can reference columns from the associated table and columns from tables in parent elements. The join condition can also have scalar filtering conditions. A top element's join condition may only specify scalar conditions.

Each set of sibling child nodes is delimited by braces {}. The top level of the view typically consists of one element in the outermost braces. This element has itself a child list delimited by braces. Each such list can have more than one different element.

Each element specifies:

- SQL table

- Correlation name for use in subsequent joins for this table

- XML element name to use for delimiting a row of this table

- List of columns, with optional XML element or attribute names

- join condition - will relate rows of this table to rows of the table in the enclosing element. If this element is at the top level, this can only consist of scalar conditions

- Optional PRIMARY KEY clause, needed if the table in this element is a view, does not have a primary key or if a non-primary key unique identity is desired

- Optional ELEMENT flag

- Optional list of child elements, delimited by braces

The column list can mention a single column or a single column renamed into an XML attribute of a different name. If a column of a table is referenced in a subsequent join condition it must appear in the output columns list. Expressions are not directly allowed but a view with expression columns can be used.

The opt_public clause, when present, offers a shorthand for calling xml_view_publish at the same time as making the definition. This makes a DAV resource reflecting the contents of the view. The contents may either be generated on demand or persisted as a DAV accessible XML document. In the latter case the document may be regenerated at a fixed interval. The interval is expressed in minutes.

The path is expressed as an absolute path from the root collection of the DAV server.

## Examples

    create xml view "cat" as
    {
      "Demo"."demo"."Categories" "C" as "category"
    	("CategoryID", "Description" as "description")
        {
          "Demo"."demo"."Products" "P" as "product"  ("ProductName")
    	on ("P"."CategoryID" = "C"."CategoryID")
        }
    }

This declares a two level hierarchy with a category node for each category and a product child node for each product in the category.

    create xml view "cats_e" as
      select "category"."CategoryID", "CategoryName",
        "ProductName", "ProductID"
        from "Demo".."Categories" "category", "Demo".."Products" as "product"
        where "product"."CategoryID" = "category"."CategoryID" element;

Here is a similar example, this time using the element option.

    create xml view "product" as
    {
      "Demo"."demo"."Products" p as "product"
          ("ProductID", "ProductName" as "product_name","UnitPrice" as "price", "SupplierID","CategoryID")
        {
          "Demo"."demo"."Suppliers" s as "supplier"  ("CompanyName")
    	on (s."SupplierID" = p."SupplierID")
           ,
          "Demo"."demo"."Categories_aux" c as "category"  ("Description")
    	on (c."CategoryID" = p."CategoryID")

        }
    }

This declares a two level hierarchy with a product node for each product and a supplier and category children node for each supplier and category in the product.