[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Entities in XML Schemas [OT?]


Subject: Re: [xsl] Entities in XML Schemas [OT?]
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Mon, 13 Oct 2003 14:52:27 +0100

Hi Ragulf,

> I do not know if this is off topic for this list. If that is the
> case, then please direct me to the right place.

This is off-topic because it doesn't have anything to do with XSLT.
The best place for your question is xmlschema-dev@xxxxxxx But I'll
mention XSLT 2.0 below in order to bring it on-topic while still
answering your question ;)

> Having an XML document somewhat like:
>
> <doc>
>   <text>This is <Bold/>bold</Bold> text</text>
>   <text>Look at comment<Comment>Beware!</Comment> to be sure you have 
> understood everything</text>
>   <text><Bold><Italic>Both bold and italic text</Italic></Bold></text>
> </doc>
>
> in DTD I would have something like:
>
> <!-- snip -->
> <!ENTITY % Inline "Bold|Italic|Uline|Comment;">
> <!ELEMENT text (#PCDATA|%Inline;)*>
> <!ELEMENT Bold (#PCDATA|%Inline;)*>
> <!ELEMENT Italic (#PCDATA|%Inline;)*>
> <!-- Snip -->
>
> The entity contains numerous other types than those shown.
>
> Now I at trying to convert to XML Schema, but I don't know how to do 
> entities like this in schema.
> I have Eric van der Vlist's XML Schema book, but have found no examples of 
> this kind.

This is a classic example of where you should use "element
substitution groups" in XML Schema. See Page 197 on in Eric's book.

First, declare an abstract element called, for example, "_Inline", of
a common type called, for example, Inline:

<xs:element name="_Inline" type="Inline" abstract="true" />

and then say that the other elements that you want to allow inline are
members of that substitution group:

<xs:element name="Bold" substitutionGroup="_Inline" />
<xs:element name="Italic" substitutionGroup="_Inline" />
<xs:element name="Comment" substitutionGroup="_Inline" />

This says that wherever a content model allow the <_Inline> element,
you can instead provide a <Bold>, <Italic> or <Comment> element. And
that the content of the <Bold>, <Italic> and <Comment> elements is
specified by the "Inline" type (they inherit it from the head of their
substitution group).

The Inline type should allow mixed content, with any number of
<_Inline> elements:

<xs:complexType name="Inline" mixed="true">
  <xs:sequence>
    <xs:element ref="_Inline" minOccurs="0" maxOccurs="unbounded" />
  </xs:sequence>
</xs:complexType>

and the <text> element should be declared with this type as well:

<xs:element name="text" type="Inline" />

The <text> element shouldn't be part of the _Inline substitution group
because it's not allowed inline.

In XSLT 2.0, with a schema-aware processor, you can then write
node tests that match any element that's a member of the _Inline
substitution group. For example, to have a template that does the same
thing with all members of the _Inline substitution group, you can do,
for example:

<xsl:template match="element(_Inline)">
  <span class="{local-name(.)}">
    <xsl:apply-templates />
  </span>
</xsl:template>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords