Skip to content

Instantly share code, notes, and snippets.

@croensch
Last active July 15, 2020 16:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save croensch/ab3d41deec01e4b45c396119b23a8ed5 to your computer and use it in GitHub Desktop.
Save croensch/ab3d41deec01e4b45c396119b23a8ed5 to your computer and use it in GitHub Desktop.

XML Schema Best Practices for Databinding

empty elements

Most programming languages implement unitialized values as NULL, ZERO, random data, something special (JavaScript: undefined) or an empty string. In XML an element can be empty in two ways and in DOM the textContent property is an empty string for both.

Valid examples:

<TodoItem/>
<TodoItem></TodoItem>

So it should be interpreted as:

$TodoItem = "";
var TodoItem = "";

NULL: XsiNil

Most programming languages implement NULL values.

Best Practice:

  • In the XSD: a value element may be marked as nillable (the default is false).
  • In the XML: the value element marked as nillable must be marked as nil.

Definition example:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element type="xs:string" nillable="true"/>
</xs:schema>

Valid example:

<TodoItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>

Invalid example:

<TodoItem/>

So it should be interpreted as:

$TodoItem = null;
TodoItem = null;

Simple Lists: SequenceOfSimpleType

Most programming languages implement a mechanism to use simple types as a list. Simple types might also be called scalar types. Simple types are for example booleans, integers, strings and floats. Simple lists might be called arrays.

Best Practices:

  • A list element should {must?} be a sequence containing one value element.
  • A list element should {must?} not have attributes. To not interfere with the items.
  • The value elements maxOccurs should be unbounded instead of the default 1. So the List can contain many items.
  • The value elements minOccurs should be 0 instead of the default 1. So the List can contain zero items.
  • The value elements nillable may be set. {JavaScript array gaps? PHP numerically-indexed array preserved?}
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="TodoList">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:string" name="TodoItem" maxOccurs="unbounded" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Valid:

<TodoList>
</TodoList>
<TodoList>
  <TodoItem>Beer</TodoItem>
</TodoList>
<TodoList>
  <TodoItem>Eggs</TodoItem>
  <TodoItem>Milk</TodoItem>
</TodoList>

Invalid:

<TodoList>
  <TodoItem/>
</TodoList>

So it should be interpreted as:

$TodoList = []; // ZERO
$TodoList = ['Beer']; // ONE
$TodoList = ['Eggs', 'Milk']; // MANY
TodoList = []; // ZERO
TodoList = ["Beer"]; // ONE
TodoList = ["Eggs", "Milk"]; // MANY

Note how the element name TodoItem has no relevance to the code.

Complex lists: SequenceOfComplexType

Most programming languages implement a mechanism to use non-simple types as a list too. Complex types might also be called non-scalar types, structs, classes or anonymous objects. Complex lists might be called arrays too.

Best Practices:

  • *all simple list best practices apply, please read these first
  • The value elements type may be a globally defined complex type. To improve readability only.
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="TodoItemType">
    <xs:all>
      <xs:element type="xs:string" name="text"/>
      <xs:element type="xs:boolean" name="done" nillable="true"/>
    </xs:sequence>
  </xs:all>
  <xs:element name="TodoList">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="TodoItem" type="TodoItemType" maxOccurs="unbounded" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Valid:

<TodoList>
</TodoList>
<TodoList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <TodoItem>
    <text>beer</text>
    <done xsi:nil="true">
  </TodoItem>
</TodoList>
<TodoList>
  <TodoItem>
    <text>Eggs</text>
    <done>true</done>
  </TodoItem>
  <TodoItem>
    <text>Milk</text>
    <done>false</done>
  </TodoItem>
</TodoList>

Invalid example:

<TodoList>
  <TodoItem>
    <text/>
  <TodoItem>
</TodoList>

This does not fail because the text element is empty - that is still a valid empty string. This does fail because the done element is missing, which is not allowed by the complex type.

So it should be interpreted as:

$TodoList = [];
$TodoList[0] = new stdClass();
$TodoList[0]->text = "Beer";
$TodoList[0]->done = null;
TodoList = {
  "text": "Beer",
  "done": null
};

Dictionary / hash map

Many programming languages implement a special type for key and value list. In XML Schema one might define a complex list for this.

SECTION UNDER CONSTRUCTION :: THIS DOES NOT MAKE SENSE YET

Best Practice:

  • The value item should use an attribute of the simple type string that is required.
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="TodoList">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:string" name="TodoItem" maxOccurs="unbounded" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Valid example:

<TodoList>
  <TodoItem identifier="45676773">
    <text>Eggs</text>
    <done>true</done>
  </TodoItem>
  <TodoItem identifier="4d696c6b">
    <text>Milk</text>
    <done>false</done>
  </TodoItem>
</TodoList>

So it should be interpreted as:

$TodoList = [];
$TodoList[0] = new stdClass();
$TodoList[0]->identifier = ''
$TodoList[0]->text = "Beer";
$TodoList[0]->done = null;
$TodoList[1] = new stdClass();
$TodoList[1]->identifier = ''
$TodoList[1]->text = "Beer";
$TodoList['4d696c6b']->done = null;
TodoList = {
  "text": "Beer",
  "done": null
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment