Reputation: 9130
I'm writing a schema for XML files that describe chapters of articles, papers, books, whatever. The highlevel concept is that a <chapter>
can have any number of paragraphs <par>
, sections <section>
, images and lists. Now, the same holds for a section, it too can have any number of paragraphs, images, lists; so can subsections (not implemented yet).
My current schema looks is this:
<xs:complexType name="chapter-type">
<xs:choice maxOccurs="unbounded">
<xs:element name="section" type="section-type" />
<xs:element name="par" type="par-type" />
<xs:element name="image" type="image-type" />
<xs:element name="ol" type="list-type" />
<xs:element name="ul" type="list-type" />
</xs:choice>
</xs:complexType>
<xs:complexType name="section-type">
<xs:choice maxOccurs="unbounded">
<xs:element name="par" type="par-type" />
<xs:element name="image" type="image-type" />
<xs:element name="ol" type="list-type" />
<xs:element name="ul" type="list-type" />
</xs:choice>
</xs:complexType>
<!-- <subsection> and other content-containing elements will repeat the par, image, ol, ul -->
As you can see, there is a lot of repetition and it'll get "worse" with subsections and other places where I'd like to reuse the content of a chapter/section.
I could add a new element, say <content>
or whatever, to wrap the paragraphs/image/lists but that would then require me to add that element into my XML. And that's what I'd like to avoid.
So my question is: how can I avoid repeating these elements everywhere?
Upvotes: 5
Views: 593
Reputation: 25034
Use named groups.
<xs:group name="paragraphs-etc">
<xs:choice>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="par" type="par-type" />
<xs:element name="image" type="image-type" />
<xs:element name="ol" type="list-type" />
<xs:element name="ul" type="list-type" />
</xs:choice>
</xs:choice>
</xs:group>
Then refer to the groups from your complex types:
<xs:complexType name="chapter-type">
<xs:choice maxOccurs="unbounded">
<xs:element name="section" type="section-type" />
<xs:group ref="paragraphs-etc"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="section-type">
<xs:group ref="paragraphs-etc"/>
</xs:complexType>
The repetition information for a group reference comes from the group reference, not the group definition. (Hence the wrapping of the paragraphs-etc group in an otherwise unnecessary xs:choice -- it ensures that any reference to the group is a reference to a repeatable set of choices.)
Upvotes: 6