1
votes

I am creating an XSD schema and I need to define complexType elements that are mixed (have both text and elements) but I need to require these to be non-empty. For simpleType there is minLength but I don't know how to (or if it is possible) to restrict this for a mixed complexType.

To illustrate the need, take the following examples in which there is a 'text' root element and the mixed complexType is 'name':

"<text></text>"  <= Valid
"<text>His name was <name>John <unk/> Mal<del>c</del>kovich</name>.</text>"  <= Valid
"<text>His name was <name>John Malkovich</name>.</text>"  <= Valid
"<text>A person called <name></name> was outside.</text>"  <= Invalid

Right now I have the following schema which gives valid to the last example, but I need it to be invalid. How can TextType be required to be non-empty?

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

  <!--==============-->
  <!-- ROOT ELEMENT -->
  <!--==============-->
  <xs:element name="text">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:group ref="TextTypeChoice"/>
        <xs:element name="name" type="NameType" maxOccurs="unbounded"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <!--==============================-->
  <!-- Group for Text type elements -->
  <!--==============================-->
  <xs:group name="TextTypeChoice">
    <xs:choice>
      <xs:element name="unk" type="EmptyType" maxOccurs="unbounded"/>
      <xs:element name="del" type="RawTextType" maxOccurs="unbounded"/>
    </xs:choice>
  </xs:group>

  <!--=============================-->
  <!-- Definition of the Text type -->
  <!--=============================-->
  <xs:complexType name="TextType" mixed="true">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:group ref="TextTypeChoice"/>
    </xs:choice>
  </xs:complexType><!--TextType-->

  <!--=============================-->
  <!-- Definition of the Name type -->
  <!--=============================-->
  <xs:complexType name="NameType">
    <xs:complexContent>
      <xs:extension base="TextType"/>
    </xs:complexContent>
  </xs:complexType><!--NameType-->

  <!--===================-->
  <!-- Type for raw text -->
  <!--===================-->
  <xs:simpleType name="RawTextType">
    <xs:restriction base="xs:token">
      <xs:minLength value="1"/>
    </xs:restriction>
  </xs:simpleType><!--RawTextType-->

  <!--========================================-->
  <!-- Type for empty / self-closing elements -->
  <!--========================================-->
  <xs:simpleType name="EmptyType">
    <xs:restriction base="xs:string">
      <xs:maxLength value="0"/>
    </xs:restriction>
  </xs:simpleType><!--EmptyType-->

</xs:schema>
1
Could you not just require the elements such as name to be non-empty?kjhughes
@kjhughes name is a NameType which I need it to be a mixed complexType. Precisely the problem is I don't know how to restrict the text of a mixed complexType.Mauricio Villegas
So, you'd like NameType elements to be mixed recursively, and they can be empty, but they cannot contain other empty NameType elements?kjhughes
Unfortunately it seems that what I want is not possible. There is no "control over the child text nodes whose values cannot be constrained at all" (docstore.mik.ua/orelly/xml/schema/ch07_05.htm) for mixed complexTypes. Furthermore, this question might be considered a duplicate of stackoverflow.com/questions/7979159/…Mauricio Villegas

1 Answers

0
votes

Options

  1. In XSD 1.0, you can support your model, if I understand it correctly, by making some adjustments:

    • Have a separate type for the text root element whose content model allows it to have mixed content, possibly empty, that includes name, del, and unk.

    • Globally (not just within text) disallow name, del, and unk from being empty.

  2. In XSD 1.1, you can support your model via assertions that can force different constraints to occur within text than exist globally:

    <xs:assert test="every $e in .//* satisfies $e != ''"/>