[Zope3-checkins] CVS: Zope3/doc/zcml - zcml.rng:1.1 zcmlrng.txt:1.1

Martijn Faassen m.faassen at vet.uu.nl
Wed Aug 27 14:21:44 EDT 2003


Update of /cvs-repository/Zope3/doc/zcml
In directory cvs.zope.org:/tmp/cvs-serv25175

Added Files:
	zcml.rng zcmlrng.txt 
Log Message:
Check in first version of the Relax NG schema for ZCML. It validates
all ZCML in the main Zope 3 source tree except for zope.app.configure test 
files. The schema itself can use further tightening and refactoring,
but it does work.


=== Added File Zope3/doc/zcml/zcml.rng ===
<grammar 
    xmlns="http://relaxng.org/ns/structure/1.0"
    xmlns:zope="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    xmlns:gts="http://namespaces.zope.org/gts" 
    xmlns:event="http://namespaces.zope.org/event"
    xmlns:help="http://namespaces.zope.org/help"
    xmlns:fssync="http://namespaces.zope.org/fssync"
    xmlns:meta="http://namespaces.zope.org/meta"
    xmlns:server-control="http://namespaces.zope.org/server-control"
    xmlns:tales="http://namespaces.zope.org/tales"
    xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
    xmlns:rdb="http://namespaces.zope.org/rdb"
    xmlns:dav="http://namespaces.zope.org/dav"
    xmlns:workflow="http://namespaces.zope.org/workflow"
    xmlns:mail="http://namespaces.zope.org/mail"
    xmlns:xml="http://namespaces.zope.org/xml"
    xmlns:startup="http://namespaces.zope.org/startup"
    xmlns:code="http://namespaces.zope.org/code"
    xmlns:renderer="http://namespaces.zope.org/renderer">

  <start>
    <element name="zope:configure">
      <optional>
        <attribute name="i18n_domain" />
      </optional>
      <optional>
        <attribute name="package" />
      </optional>
      <ref name="configure_content" />
    </element>
  </start>

  <define name="sub_configure">
    <element name="zope:configure">
      <optional>
        <attribute name="i18n_domain" />
       </optional>
      <ref name="configure_content" />
    </element>
  </define>

  <define name="configure_content">
      <zeroOrMore>
      <choice>
        <!-- can nest this apparently to do i18n_domains -->
        <ref name="sub_configure" />

        <!-- core zcml namespace -->
        <ref name="include" />
        <ref name="includeOverrides" />
        <ref name="grant" />
        <ref name="principal" />
        <ref name="unauthenticatedPrincipal" />
        <ref name="role" />
        <!-- <ref name="permission" /> --> 
        <ref name="serviceType" />
        <ref name="content" />
        <ref name="adapter" />
        <ref name="view" />
        <ref name="defaultView" />
        <ref name="utility" />
        <ref name="service" />
        <ref name="class" />
        <ref name="hook" />
        <ref name="interface" />
        <ref name="permission" />
        <ref name="securityPolicy" />
        <ref name="factory" />
        <ref name="traversalNamespace" />
        <ref name="vocabulary" />

        <!-- browser -->
        <ref name="browser_defaultView" />
        <ref name="addform" />
        <ref name="editform" />
        <ref name="page" />
        <ref name="pages" />
        <ref name="menu" />
        <ref name="menuItem" />
        <ref name="menuItems" />
        <ref name="browser_view" />
        <ref name="icon" />
        <ref name="skin" />
        <ref name="resource" />
        
        <!-- help -->
        <ref name="register" />
        
        <!-- fssync -->
        <ref name="fssync_adapter" />

        <!-- gts -->      
        <ref name="registerTranslations" />
        <ref name="defaultLanguages" />

        <!-- event -->
        <ref name="subscribe" />
 
        <!-- meta -->
        <ref name="directives" />
        <ref name="top_directive" />

        <!-- server-control -->
        <ref name="registerShutdownHook" />

        <!-- tales -->
        <ref name="namespace" />

        <!-- xmlrpc -->
        <ref name="xmlrpc_view" />
        <ref name="xmlrpc_defaultView" />

        <!-- rdb -->
        <ref name="provideConnection" />

        <!-- dav -->
        <ref name="provideInterface" />

        <!-- workflow -->
        <ref name="importHandler" />
        <ref name="exportHandler" />

        <!-- mail -->
        <ref name="queuedService" />
        <ref name="directService" />
        <ref name="sendmailMailer" />
        <ref name="smtpMailer" />
 
        <!-- xml -->
        <ref name="schemaInterface" />

        <!-- startup -->
        <ref name="registerServerType" />
        <ref name="registerRequestFactory" />

        <!-- code -->
        <ref name="registerInterpreter" />

        <!-- renderer -->
        <ref name="sourcetype" />
        <ref name="renderer" />

      </choice>
      </zeroOrMore>
  </define>

  <!-- zcml -->

  <define name="include">
    <element name="zope:include">
      <optional>
        <!-- defaults to '.' package -->
        <attribute name="package" />
      </optional>
      <optional>
        <!-- defaults to 'configure.zcml' -->
        <attribute name="file" />
      </optional>
    </element>
  </define>

  <define name="includeOverrides">
    <element name="zope:includeOverrides">
      <attribute name="file" />
    </element>
  </define>

  <define name="grant">
    <element name="zope:grant">
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="role" />
      </optional>
      <optional>
        <attribute name="principal" />
      </optional>
    </element>
  </define>

  <define name="principal">
    <element name="zope:principal">
      <attribute name="id" />
      <attribute name="title" />
      <optional>
        <attribute name="description" />
      </optional>
      <attribute name="login" />
      <attribute name="password" />
    </element>
  </define>

  <define name="unauthenticatedPrincipal">
    <element name="zope:unauthenticatedPrincipal">
      <attribute name="id" />
      <attribute name="title" />
    </element>
  </define>

  <define name="role">
    <element name="zope:role">
      <attribute name="id" />
      <attribute name="title" />
      <optional>
        <attribute name="description" />
      </optional>
    </element>
  </define>

  <define name="serviceType">
    <element name="zope:serviceType">
      <attribute name="id" />
      <attribute name="interface" />
    </element>
  </define>

  <define name="content">
    <element name="zope:content">
      <attribute name="class" />
      <interleave>
        <optional>
          <!-- perhaps mandatory? -->
          <element name="zope:factory">
            <optional>
              <attribute name="permission" />
            </optional>
            <optional>
              <attribute name="id" />
            </optional>
            <optional>
              <attribute name="title" />
            </optional>
            <optional>
              <attribute name="description" />
            </optional>
          </element>
        </optional>
        <zeroOrMore>
          <element name="zope:allow">
            <optional>
              <attribute name="interface" />
            </optional>
            <optional>
              <attribute name="attributes" />
            </optional>
          </element>
        </zeroOrMore>
        <zeroOrMore>
          <element name="zope:implements">
            <attribute name="interface" />
          </element>
        </zeroOrMore>
        <zeroOrMore>
          <ref name="require" />
        </zeroOrMore>
        </interleave>
    </element>
  </define>

  <define name="adapter">
    <element name="zope:adapter">
      <attribute name="for" />
      <attribute name="factory" />
      <attribute name="provides" />
      <optional>
        <attribute name="name" />
      </optional>
      <optional>
        <attribute name="permission" />
      </optional>
    </element>
  </define>

  <define name="view">
    <element name="zope:view">
      <attribute name="for" />
      <attribute name="name" />
      <attribute name="factory" />
      <attribute name="type" />
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="allowed_interface" />
      </optional>
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
    </element>
  </define>

  <define name="defaultView">
    <element name="zope:defaultView">
      <attribute name="for" />
      <attribute name="type" />
      <attribute name="name" />
      <attribute name="permission" />
      <attribute name="factory" />
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
    </element>
  </define>

  <define name="utility">
    <element name="zope:utility">
      <attribute name="provides" />
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="factory" />
      </optional>
      <optional>
        <attribute name="component" />
      </optional>
    </element>
  </define>

  <define name="service">
    <element name="zope:service">
      <attribute name="serviceType" />
      <attribute name="component" />
      <optional>
        <attribute name="permission" />
      </optional>
    </element>
  </define>

  <define name="hook">
    <element name="zope:hook">
      <attribute name="module" />
      <attribute name="name" />
      <attribute name="implementation" />
    </element>
  </define>

  <define name="interface">
    <element name="zope:interface">
      <attribute name="interface" />
    </element>
  </define>

  <define name="class">
    <element name="zope:class">
      <attribute name="class" />
      <ref name="require" />
    </element>
  </define>

  <define name="permission">
     <element name="zope:permission">
       <attribute name="id" />
       <attribute name="title" />
       <optional>
         <attribute name="description" />
       </optional>
     </element>
  </define>

  <define name="securityPolicy">
     <element name="zope:securityPolicy">
       <attribute name="component" />
     </element>
  </define>

  <define name="require">
    <element name="zope:require">
      <choice>
         <ref name="require_normal" />
         <ref name="require_like_class" />
      </choice>
     </element>
  </define>
  
  <define name="traversalNamespace">
    <element name="zope:traversalNamespace">
      <attribute name="name" />
      <attribute name="handler" />
    </element>
  </define>

  <define name="vocabulary">
    <element name="zope:vocabulary">
      <attribute name="name" />
      <attribute name="factory" />
      <optional>
        <attribute name="filter" />
      </optional>
      <optional>
        <attribute name="another" />
      </optional>
    </element>
  </define>

  <define name="require_normal">
    <attribute name="permission" />
      <optional>
        <attribute name="attributes" />
      </optional>
      <optional>
        <attribute name="interface" />
      </optional>
      <!-- XXX ? -->
      <optional>
        <attribute name="set_schema" />
      </optional>
      <optional>
        <attribute name="set_attributes" />
      </optional>
  </define>

  <define name="require_like_class">
    <attribute name="like_class" />
  </define>

  <define name="factory">
    <element name="zope:factory">
      <attribute name="component" />
      <attribute name="id" />
    </element>
  </define>

  
  <!-- browser -->
  <define name="browser_defaultView">
    <element name="browser:defaultView">
      <attribute name="name" />
      <optional>
        <attribute name="for" />
      </optional>
    </element>
  </define>

  <define name="addform">
    <element name="browser:addform">
      <attribute name="name" />
      <attribute name="schema" />
      <attribute name="permission" />
      <attribute name="content_factory" />
      <optional>
        <attribute name="menu" />
      </optional>
      <optional>
        <attribute name="for" />
      </optional>
      <optional>
        <attribute name="arguments" />
      </optional>
      <optional>
        <attribute name="keyword_arguments" />
      </optional>
      <optional>
        <attribute name="fields" />
      </optional>
      <optional>
        <attribute name="class" />
      </optional>
      <optional>
        <attribute name="label" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <optional>
        <!-- XXX used anywhere? -->
        <attribute name="set_before_add" />
      </optional>
      <optional>
        <attribute name="set_after_add" />
      </optional>
      <optional>
        <attribute name="description" />
      </optional>
    </element>
  </define>

  <define name="editform">
    <element name="browser:editform">
      <attribute name="schema" />
      <attribute name="name" />
      <attribute name="permission" />
      <optional>
        <attribute name="menu" />
      </optional>
      <optional>
        <attribute name="for" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <optional>
        <attribute name="template" />
      </optional>
      <optional>
        <attribute name="label" />
      </optional>
      <optional> 
        <attribute name="class" />
      </optional>
      <optional>
        <attribute name="fields" />
      </optional>
    </element>
  </define>

  <define name="menu">
    <element name="browser:menu">
      <attribute name="id" />
      <attribute name="title" />
      <optional>
        <attribute name="usage" />
      </optional>
    </element>
  </define>

  <define name="menuItem">
    <element name="browser:menuItem">
      <attribute name="menu" />
      <attribute name="for" />
      <attribute name="title" />
      <attribute name="action" />
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="description" />
      </optional>
      <optional>
        <attribute name="filter" />
      </optional>
    </element>
  </define>

  <define name="menuItems">
    <element name="browser:menuItems">
      <attribute name="for" />
      <attribute name="menu" />
      <oneOrMore>
        <element name="browser:menuItem">
          <attribute name="title" />
          <attribute name="action" />
          <optional>
            <attribute name="filter" />
          </optional>
          <optional>
            <attribute name="permission" />
          </optional>
        </element>
      </oneOrMore>
    </element>
  </define>

  <define name="pages">
    <element name="browser:pages">
      <attribute name="for" />
      <attribute name="class" />
      <attribute name="permission" />
      <oneOrMore>
        <ref name="subpage" />
      </oneOrMore>
    </element>
  </define>

  <define name="browser_view">
    <element name="browser:view">
      <attribute name="for" />
      <attribute name="name" />
      <attribute name="class" />
      <attribute name="permission" />
      <optional>
        <attribute name="menu" />
      </optional>
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <zeroOrMore>
        <ref name="subpage" />
      </zeroOrMore>
    </element>
  </define>

  <define name="subpage">
    <element name="browser:page">
      <attribute name="name" />
      <optional>
        <attribute name="attribute" />
      </optional>
      <optional>
        <attribute name="template" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <optional>
        <attribute name="menu" />
      </optional>
    </element>
  </define>

  <!-- XXX page directive defined in a different way if it's subpage -->
  <define name="page">
    <element name="browser:page">
      <attribute name="name" />
      <attribute name="for" />
      <attribute name="permission" />
      <optional>
        <attribute name="class" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <optional>
        <attribute name="menu" />
      </optional>
      <optional>
        <attribute name="attribute" />
      </optional>
      <optional>
        <attribute name="template" />
      </optional>
      <optional>
        <attribute name="allowed_interface" />
      </optional>
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
      <optional>
        <attribute name="layer" />
      </optional>
    </element>
  </define>

  <define name="icon">
    <element name="browser:icon">
      <attribute name="name" />
      <attribute name="for" />
      <attribute name="file" />
    </element>
  </define>

  <define name="skin">
    <element name="browser:skin">
      <attribute name="name" />
      <attribute name="layers" />
    </element>
  </define>

  <define name="resource">
    <element name="browser:resource">
      <attribute name="name" />
      <attribute name="file" />
      <optional>
        <attribute name="layer" />
      </optional>
    </element>
  </define>

  <!-- help -->
  <define name="register">
    <element name="help:register">
      <attribute name="id" />
      <attribute name="title" />
      <attribute name="doc_path" />
      <optional>
        <attribute name="for" />
      </optional>
      <optional>
        <attribute name="view" />
      </optional>
      <optional>
        <attribute name="parent" />
      </optional>
    </element>
  </define>

  <!-- fssync -->
  <define name="fssync_adapter">
    <element name="fssync:adapter">
      <attribute name="factory" />
      <optional>
        <attribute name="class" />
      </optional>
    </element>
  </define>

 
  <!-- gts -->
  <define name="registerTranslations">
    <element name="gts:registerTranslations">
      <attribute name="directory" />
    </element>
  </define>

  <define name="defaultLanguages">
    <element name="gts:defaultLanguages">
      <attribute name="languages" />
    </element>
  </define>

  <!-- event -->
  <define name="subscribe">
    <element name="event:subscribe">
      <attribute name="subscriber" />
      <attribute name="event_types" />
    </element>
  </define>

  <!-- meta -->

  <define name="top_directive">
    <element name="meta:directive">
      <attribute name="namespace" />
      <attribute name="name" />
      <attribute name="schema" />
      <attribute name="handler" />
    </element>
  </define>

  <define name="directives">
    <element name="meta:directives">
      <attribute name="namespace" />
      <oneOrMore>
        <choice>
          <ref name="directive" />
          <ref name="complexDirective" />
        </choice>
      </oneOrMore>
    </element>
  </define>

  <define name="directive">
    <element name="meta:directive">
      <attribute name="name" />
      <attribute name="schema" />
      <attribute name="handler" />
    </element>
  </define>

  <define name="complexDirective">
    <element name="meta:complexDirective">
      <attribute name="name" />
      <attribute name="schema" />
      <attribute name="handler" />
      <zeroOrMore>
        <ref name="subdirective" />
      </zeroOrMore>
    </element>
  </define>

  <define name="subdirective">
    <element name="meta:subdirective">
      <attribute name="name" />
      <attribute name="schema" />
     </element>
  </define>

  <!-- server-control -->
  <define name="registerShutdownHook">
    <element name="server-control:registerShutdownHook">
      <attribute name="name" />
      <attribute name="priority" />
      <attribute name="call" />
    </element>
  </define>

  <!-- tales -->
  <define name="namespace">
    <element name="tales:namespace">
      <attribute name="prefix" />
      <attribute name="interface" />
    </element>
  </define>

  <!-- xmlrpc -->
  <define name="xmlrpc_view">
    <element name="xmlrpc:view">
      <attribute name="name" />
      <attribute name="for" />
      <optional>
        <attribute name="class" />
      </optional>
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="allowed_interface" />
      </optional>
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
      <optional>
        <attribute name="factory" />
      </optional>
    </element>
  </define>

  <define name="xmlrpc_defaultView">
    <element name="xmlrpc:defaultView">
      <attribute name="name" />
      <attribute name="for" />
    </element>
  </define>

  <!-- rdb -->
  <define name="provideConnection">
    <element name="rdb:provideConnection">
      <attribute name="name" />
      <attribute name="component" />
      <attribute name="dsn" />
    </element>
  </define> 

  <!-- dav -->
  <define name="provideInterface">
    <element name="dav:provideInterface">
      <attribute name="for" />
      <attribute name="interface" />
    </element>
  </define>

  <!-- workflow -->
  <define name="importHandler">
    <element name="workflow:importHandler">
      <attribute name="interface" />
      <attribute name="factory" />
    </element>
  </define>

  <define name="exportHandler">
    <element name="workflow:exportHandler">
      <attribute name="interface" />
      <attribute name="factory" />
    </element>
  </define>

  <!-- mail -->
  <define name="queuedService">
    <element name="mail:queuedService">  
      <attribute name="name" />
      <attribute name="queuePath" />
      <attribute name="mailer" />
      <attribute name="permission" />
    </element>
  </define>

  <define name="directService"> 
    <element name="mail:directService">
      <attribute name="name" />
      <attribute name="mailer" />
      <attribute name="permission" />
    </element>
  </define>

  <define name="sendmailMailer">
    <element name="mail:sendmailMailer">
       <attribute name="id" />
       <optional>
         <attribute name="command" />
       </optional>
    </element>
  </define>

  <define name="smtpMailer">
    <element name="mail:smtpMailer">
      <attribute name="id" />
      <attribute name="hostname" />
      <optional>
        <attribute name="port" />
      </optional>
      <optional>
        <attribute name="username" />
      </optional>
      <optional>
        <attribute name="password" />
      </optional>
    </element>
  </define>

  <!-- xml -->
  <define name="schemaInterface">
    <element name="xml:schemaInterface">
      <attribute name="uri" />
    </element>
  </define>

  <!-- startup -->
  <define name="registerServerType">
    <element name="startup:registerServerType">
      <attribute name="name" />
      <attribute name="factory" />
      <attribute name="requestFactory" />
      <attribute name="logFactory" />
      <attribute name="defaultPort" />
      <attribute name="defaultVerbose" />
    </element>
 </define>

  <define name="registerRequestFactory"> 
    <element name="startup:registerRequestFactory">
      <attribute name="name" />
      <optional> 
        <attribute name="publication" />
      </optional>
      <optional>
        <attribute name="factory" />
      </optional>
      <optional>
        <attribute name="request" />
      </optional>
    </element>
  </define>

  <!-- code -->
  <define name="registerInterpreter">
    <element name="code:registerInterpreter">
      <attribute name="type" />
      <attribute name="component" />
    </element>
  </define>

  <!-- renderer -->
  <define name="sourcetype">
    <element name="renderer:sourcetype">
      <attribute name="title" />
      <attribute name="interface" />
      <attribute name="class" />
    </element>
  </define>
  
  <define name="renderer">
    <element name="renderer:renderer">
      <!-- XXX different case spelling for sourceType/sourcetype here -->
      <attribute name="sourceType" />
      <attribute name="for" />
      <attribute name="factory" />
    </element>
  </define>
 
</grammar>



=== Added File Zope3/doc/zcml/zcmlrng.txt ===
zcml.rng is a Relax NG schema that can validate (at the time of
writing) all the .zcml files in the Zope 3 core source tree.  The only
exception to this is in zope/app/configure. There are tests there
which test zcml and make different assumptions than the schema do.

The schema is based on actual usage of ZCML. The code may actually
define directives and optional attributes that are never ever used or
tested. They are not part of the schema.

The schema is not finished yet. It can be tightened further and it can
be refactored to reuse more common information; many directives share
some attributes. It can also be made more modular by splitting up the
different namespaces into separate files.

You should be able to validate a ZCML file against the schema by using
any Relax NG processor. I've used libxml2's implementation through
xmlllint, using the following command:

xmllint --noout --relaxng zcml.rng somefile.zcml

At the time of writing the most recent release of libxml (2.5.10)
contains a bug which causes a segfault under certain circumstances. A
recent CVS checkout of libxml2 has a fix.




More information about the Zope3-Checkins mailing list