2007/2/23, fantasai <[EMAIL PROTECTED]>:

Henri Sivonen wrote:
>
> Moreover, trying to implementing exclusions in the main RELAX NG
> schema causes the number of grammar production to roughly double per
> each exclusion pair. This kind of growth is not manageable in a human-
> written schema.

The difficult characteristic of HTML 5, schema-wise, is that it propagates
several different content model restrictions *through* descendants:
Interactive elements cannot not have interactive descendants, and many
elements can be used in two different inline model contexts: structured
and strict. Currently I have four different inline content models going
in parallel, with four definitions of each inline element. Adding in
another facet would push that up to eight, which is too unweildy. Try
to add in the "significant content" requirement, which is applied to
elements like <p> and <a>, plus another handful of random per-element
exclusions and a Relax NG schema without some kind of grammar intersection
quickly becomes very impractical.

<snip/>

Intersection would also let me do things like require a common optional
attribute on a particular element ( e.g. 'dir' on <bdo>) while still
using the named common attribute collection (instead of duplicating the
common attributes specially just for <bdo>).



This looks like something I did in a relaxng schema in 2004. I've included a
simplistic schema example inline below, plus an xml instance for testing the
validation (test.xml). The schema works with oXygen's autocompletion.

What I wanted was to include a recursive structure of elements, with an
arbitrary depth. In certain contexts I wanted specific elements to be
excluded, banned from the whole structure. I wanted to pass a parameter down
the structure that we are now in a disallow-elements-a-and-b context. In
that way I could avoid duplicating the element definitions.

I ended up doing exclusion by grammar inclusion, using two files.

  - The context is defined as a sub-grammar in the main file
(test.rngin the example).
  - The elements of the structure are defined in the second file (
  test2.rng in the example).
  - The elements of the structure get instructions about what
  sub-elements to allow by using a parentRef into the grammar of the context
  defined in the main file, a callback pattern.

(This example communicates between the two files using one parameter. But a
situation requiring more parameters could be easily handled.)

I hope this provides sensible input into the thread, two weeks after its
last post. Has anyone else tried doing it this way?

-tor

[test.rng]
<grammar ns="test" xmlns="http://relaxng.org/ns/structure/1.0";>
 <start>
   <element name="test">
     <empty/>
     <ref name="container-abc-element"/>
     <ref name="container-ab-element"/>
     <ref name="container-c-element"/>
   </element>
 </start>

 <define name="container-abc-element">
   <grammar>
     <include href="test2.rng"/>

     <start>
       <element name="container-abc">
         <ref name="container-choice"/>
       </element>
     </start>
     <define name="container-choice">
       <choice>
         <ref name="a-element"/>
         <ref name="b-element"/>
         <ref name="c-element"/>
       </choice>
     </define>
   </grammar>
 </define>
 <define name="container-ab-element">
   <grammar>
     <include href="test2.rng"/>

     <start>
       <element name="container-ab">
         <ref name="container-choice"/>
       </element>
     </start>
     <define name="container-choice">
       <choice>
         <ref name="a-element"/>
         <ref name="b-element"/>
       </choice>
     </define>
   </grammar>
 </define>
 <define name="container-c-element">
   <grammar>
     <include href="test2.rng"/>

     <start>
       <element name="container-c">
         <ref name="container-choice"/>
       </element>
     </start>
     <define name="container-choice">
       <choice>
         <ref name="c-element"/>
       </choice>
     </define>
   </grammar>
 </define>

</grammar>


[test2.rng ]
<grammar xmlns="http://relaxng.org/ns/structure/1.0";>

 <define name="a-element">
   <grammar>
     <start>
       <element name="a">
         <empty/>
         <optional>
           <parentRef name="container-choice"/>
         </optional>
       </element>
     </start>
   </grammar>
 </define>
 <define name="b-element">
   <grammar>
     <start>
       <element name="b">
         <empty/>
         <optional>
           <parentRef name="container-choice"/>
         </optional>
       </element>
     </start>
   </grammar>
 </define>
 <define name="c-element">
   <grammar>
     <start>
       <element name="c">
         <empty/>
         <optional>
           <parentRef name="container-choice"/>
         </optional>
       </element>
     </start>
   </grammar>
 </define>

</grammar>


[test.xml]
<test xmlns="test">
 <container-abc>
   <a>
     <b>
       <c/>
     </b>
   </a>
 </container-abc>
 <container-ab>
   <a>
     <b>
       <b/>
     </b>
   </a>
 </container-ab>
 <container-c>
   <c>
     <c>
       <c/>
     </c>
   </c>
 </container-c>
</test>

eof
-------

Reply via email to