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 -------
