The DTD for the XML format
<!-- Root element -->
<!ELEMENT GenieGate (GroupDefinitions?,
PropertyDefinitions?,
Users?)>
<!ELEMENT GroupDefinitions (GroupDefinition*)>
<!ELEMENT GroupDefinition EMPTY>
<!ATTLIST GroupDefinition gid NMTOKEN #REQUIRED>
<!ATTLIST GroupDefinition name CDATA #IMPLIED>
<!-- Flag not used -->
<!ATTLIST GroupDefinition signup (Y|N) #IMPLIED>
<!ELEMENT PropertyDefinitions (PropertySection*)>
<!ELEMENT PropertySection (PropertyDefinition*)>
<!ATTLIST PropertySection id NMTOKEN #REQUIRED>
<!ATTLIST PropertySection title CDATA #IMPLIED>
<!ELEMENT PropertyDefinition EMPTY >
<!ATTLIST PropertyDefinition property NMTOKEN #REQUIRED>
<!ATTLIST PropertyDefinition title CDATA #IMPLIED>
<!-- Container for Users, this should be in another file. -->
<!ELEMENT Users (User*) >
<!-- Container for a user. -->
<!ELEMENT User (Groups?,UserProperties*)>
<!ATTLIST User uid NMTOKEN #REQUIRED>
<!ATTLIST User email CDATA #REQUIRED>
<!ATTLIST User password CDATA #REQUIRED>
<!-- YYYY-MM-DD -->
<!ATTLIST User created NMTOKEN #IMPLIED>
<!ATTLIST User confirm (Y|U) #REQUIRED>
<!ATTLIST User name CDATA #IMPLIED>
<!-- Groups user is a member of. -->
<!ELEMENT Groups (Group*)>
<!ELEMENT Group EMPTY>
<!ATTLIST Group gid NMTOKEN #REQUIRED>
<!-- Properties grouped by a section. -->
<!ELEMENT UserProperties (UserProperty*)>
<!ATTLIST UserProperties section NMTOKEN #REQUIRED>
<!-- Only element that actually uses #PCDATA. (Since a property could
in theory contain multiple lines) -->
<!ELEMENT UserProperty (#PCDATA)>
<!ATTLIST UserProperty property NMTOKEN #REQUIRED>