Jens
Jens

Reputation: 9130

How can I reuse the same <xs:choice> in different complex type definitions?

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

Answers (1)

C. M. Sperberg-McQueen
C. M. Sperberg-McQueen

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

Related Questions