I am creating a whole bunch of Relax NG schemas and seeking to
maximize re-use of schema fragments.
I am having trouble with multiple includes and seeking advise on how
best to deal with the one-include-per-file restriction.
Here is my setup/wishlist:
All schema fragments stored in RNC and tranged via ANT to RNG/XSD/DTD.
All schema fragments are usable standalone as well as modules of
bigger schemas.
All schema fragments have their own namespace with a simple naming
convention
that mirrors the file naming convention.
All schemas take the same basic shape. Here is the basic shape (for
any schema S):
-- file S.rnc --
namespace S = "http://example.com/S"
# One of these for each schema fragment this schema uses.
# Replace XXX with schema basefilename.
include "XXX.rnc" { start |= notAllowed }
start = _S.ROOT_
_S.ROOT_ = element S:root {
...
}
-- end file S.rnc --
In an ideal world, a schema writer wishing to use another schema X as
a component, should not have to know anything about what other schema
fragments get included by schema X.
As I understand Relax NG, this is not the case. In the ASCII art below
I have tried to illustrate a situation in which schema M includes M1
and M2. M1 in turn, also includes M2.
M --|
|-- M1 --|
| |
| |-- M2
|
|
|-- M2
The resultant schema (as I understand it) is illegal because M2 is
included twice.
Back in my C programming youth, I would use use "#ifndef" :-) How best
to handle in Relax NG?
Illustrative schemas below.
Error message:
java -jar d:\data\utils\trang.jar m.rnc m.xsd
m2.rnc:5:1: error: multiple definitions of "_M2.ROOT_" without
"combine" attribute
Interestingly, tranging to RNGs does not produce multiple include
errors. Subsequent jing's complain about the duplicates
however. Tranging to XSD's does produce errors about the duplicates.
-- m.rnc --
namespace M = "http://example.com/M"
start = _M.ROOT_
include "m1.rnc" { start |= notAllowed }
include "m2.rnc" { start |= notAllowed }
_M.ROOT_ = element M:root {
# content model here
text
}
-- m1.rnc --
namespace M1 = "http://example.com/M1"
start = _M1.ROOT_
include "M2.rnc" { start |= notAllowed }
_M1.ROOT_ = element M1:root {
# model goes here
text
}
-- m2.rnc --
namespace M2 = "http://example.com/M2"
start = _M2.ROOT_
_M2.ROOT_ = element M2:root {
text
}
-- end --
I can see a couple of routes forward involving munging the locations of
includes with scripts but I do not want to launch into anything until I
have sanity checked that I have not missed the simple one line solution.
regards,
Sean
--
http://seanmcgrath.blogspot.com