This document is also available in these non-normative formats: XML.
This proposal defines a packaging system for various core XML technologies: XSLT, XQuery, and XProc. The goal is to define it in a way enough generic so to adapt it to other technologies in the future (such as XML Schema, XForms, etc.) using the same framework. Besides enabling the delivery of libraries written in standard XSLT, XQuery and XProc, it provides support for extensions specific to some processors, as well as enabling new processors to be supported by using the same framework.
1 Introduction
2 Editorial notes
3 Concepts
4 Standard X* files
4.1 XSLT
4.2 XQuery
4.3 XProc
4.4 XML Schema
4.5 RelaxNG
4.6 Schematron
4.7 NVDL
4.8 Not supported file kinds
4.9 Package example
5 Processor-specific files
5.1 Saxon
5.2 Xalan
5.3 eXist
5.4 MarkLogic
5.5 Zorba
5.6 Calabash
5.7 Calumet
5.8 xmlsh
6 Extensibility
XSLT, XQuery and XProc are amazing programming languages. But they lack a large choice of libraries, and when such libraries do exist, this is a challenge to install. There is no automatic install process, the rules are different for each processor, library authors do not follow the same rules regarding the info they provide, the cataloging, the way they reference third-party libraries, etc.
All those problems (well, most of them) can be addressed by a packaging system that would be broadly adopted by processor vendors and library authors. The cornerstone of such a system is the packaging format: a description of the information to be provided by the library authors and how to provide and structure them.
Should the package system define a set of XPath functions? Instead of just defining the package format and letting everything else as implementation-defined, should it in addition define a module of functions to install, delete, and more generally manage packages from within a processor?
Drawback: potential problems if the processor requires to be stopped?
Advantages: enables writing tools on top of the system (one single graphical package manager for one system, simply using the XPath functions, as well as easy integration within IDEs; or even other systems could be more easily be built on top of it, like a packaging system for XRX applications for instance.)
Should it be possible to have two different kinds of files with the same public URI? Put another way, should we have a different URI space for each kind of files? I think this would be necessary for instance to enable deploying a package with both an XML schema and an XQuery library module with the same target namespace. I am not sure this is a best practice, but I am sure that will lead to at least one company's standard practices...
A library is a set of files fulfilling a common purpose. An XSLT library can for
instance provide a set of template rules and functions to help formating a particular
XML document type. A package is a way to bundle those files into a single ZIP file,
following a defined structure and providing more information within the package
descriptor. The package descriptor is a plain XML file, named
expath-pkg.xml
at the root of the ZIP file, and containing information
about the library (like its name and its version number) and about the files it provides
and how to reference them (for instance stylesheets and query modules.)
The ZIP file structure (aka the package structure) must have exactly two entries at the top-level (aka the root): the package descriptor and one directory entry. This directory contains all the library files, and all file references in the package descriptor are relative to this directory. This directory is called the library directory.
All the elements in the package descriptor are defined in the namespace
http://expath.org/mod/expath-pkg
. All the elements defined in this
specification or used in samples and in text are in this namespace, even if no prefix is
used. The root element is package
, and contains exactly one child element
module
:
<package> module </package> <module name = NCName version = string> title, (xsl |xquery |xproc |xsd |rng |rnc |...)+ </module>
name
is the library name. The top-level directory in the package structure
must have the exact same name. The module has also a version number, and a
human-readable title. It then provides information about one or several files. In
addition to those standard file descriptors, it can also contain elements specific to
some processors (for instance an element for Saxon, eXist, etc.) Details are provided
below.
The files configured in the module are the files exported by the module. But the whole library directory must be preserved. Indeed, it can contain other, private files, aimed to be used only from within library files, not from the outside.
Here is the description of the standard file kinds supported by this specification, and how they contribute to the package descriptor document type.
An XSLT file is associated a public import URI. This URI must be an
absolute URI (most often a URN or an HTTP URI.) This is the URI to use in an XSLT
import instruction (aka xsl:import
) to import the XSLT file provided in
the package. This file is configured with the element xsl
.
<xsl> import-uri, file </xsl>
The element file
contains the path to the file within the package
structure, relative to the library directory. Both elements import-uri
and file
are of type anyURI
.
An XQuery library module is referenced by its namespace URI. Thus the
xquery
element associates a namespace URI to an XQuery file. An
importing module just need to use an import statement of the form import module
namespace xx = "<namespace-uri>";
.
<xquery> namespace, file </xquery>
Note that there is no way to set any location hint (as the at
clause in
the import statement.) To use this packaging system, an XQuery library module must be
referenced by its target namespace.
An XProc pipeline, like an XSLT stylesheet, is associated a public import
URI, aimed to be used in an XProc p:import
statement.
<xproc> import-uri, file </xproc>
An XML schema can be imported using its target namespace. Like for XQuery, there is
no way to use any schemaLocation
instead. There is neither the ability
to set several files as several sources for the schema. If the schema is spread over
multiple files, there must be one top-level file that includes the other files.
<xsd> namespace, file </xsd>
(TODO: Should we support schemas with empty target namespace? I am sure this is a good idea in a packaging system...)
A RelaxNG schema, like an XSLT stylesheet, is associated a public import URI, aimed to be used in an import statement (either the include element for an RNG schema or an import directive for an RNC schema.)
<rng> import-uri, file </rng> <rnc> import-uri, file </xrnc>
A Schematron schema is associated a public URI.
<schematron> import-uri, file </schematron>
Documentation (like result of XSLStyle or xqDoc) is not taken into account in the packaging format, though that could be used by IDEs for instance to provide documentation for functions in an editor with a live completion feature. Some support for documentation can of course be added as a product-specific feature to the package descriptor.
Bla-bla...
Bla-bla...
... classes for extension functions (both Java and .Net?), classes for extension instructions, classes for localizing numbers and dates, URI resolvers, etc.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:pkg="http://expath.org/mod/expath-pkg" targetNamespace="http://expath.org/mod/expath-pkg" elementFormDefault="qualified"> <xs:element name="package"> <xs:complexType> <xs:sequence> <xs:element ref="pkg:module" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="module"> <xs:complexType> <xs:sequence> <xs:element name="title" type="pkg:title-type"/> <xs:element name="xsl" type="pkg:style-type" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="xquery" type="pkg:query-type" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="saxon" type="pkg:saxon-type" minOccurs="0"/> <xs:element name="exist" type="pkg:exist-type" minOccurs="0"/> </xs:sequence> <xs:attribute name="version" type="xs:string"/> <xs:attribute name="name" type="xs:string"/> </xs:complexType> </xs:element> <xs:simpleType name="title-type"> <xs:restriction base="xs:string"/> </xs:simpleType> <xs:complexType name="style-type"> <xs:sequence> <xs:element name="import-uri" type="xs:anyURI"/> <xs:element name="file" type="xs:anyURI"/> </xs:sequence> </xs:complexType> <xs:complexType name="query-type"> <xs:sequence> <xs:element name="namespace" type="xs:anyURI"/> <xs:element name="file" type="xs:anyURI"/> </xs:sequence> </xs:complexType> <xs:complexType name="saxon-type"> <xs:sequence> <xs:element name="function" minOccurs="0" maxOccurs="unbounded" type="xs:string"/> <xs:element name="library" minOccurs="0" maxOccurs="unbounded" type="xs:string"/> <xs:element name="xsl" minOccurs="0" maxOccurs="unbounded" type="pkg:style-type"/> <xs:element name="xquery" minOccurs="0" maxOccurs="unbounded" type="pkg:query-type"/> <xs:element name="xsl-wrapper" minOccurs="0" maxOccurs="unbounded" type="pkg:style-type"/> <xs:element name="xquery-wrapper" minOccurs="0" maxOccurs="unbounded" type="pkg:query-type"/> <xs:element name="dep" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="title" type="pkg:title-type"/> <xs:element name="home" type="xs:anyURI"/> <xs:element name="href" type="xs:anyURI" minOccurs="0"/> </xs:sequence> <xs:attribute name="type" fixed="jar"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <xs:complexType name="exist-type"> <xs:sequence> <xs:element name="xquery" type="pkg:query-type" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:schema>
(or RNC?)