Dusting off the Résumé, Part 1: The Schema

I wrote my current Résumé in eXtensible Markup Language (XML), back in 2002, just before I started work at the US Naval Research Laboratory. Of course, XML, being a rather free-form markup style, it works best when constrained. At first, I did this via a Document Type Definition (DTD).

<!-- Entities -->
<!ENTITY  nbsp         "&#x00A0;">
<!ENTITY  chi2         "&#x03C7;&#x00B2;">
<!ENTITY  endash       "&#x2013;">
<!ENTITY  eacute       "&#x00E9;">
<!-- Pure (PCDATA) Elements -->
<!-- Names and Addresses -->
<!ELEMENT name         (#PCDATA)>
<!ELEMENT oldname      (#PCDATA)>
<!ELEMENT street       (#PCDATA)>
<!ELEMENT apartment    (#PCDATA)>
  <!ATTLIST apartment    spellout     (true|false) "false">
<!ELEMENT city         (#PCDATA)>
<!ELEMENT state        (#PCDATA)>
<!ELEMENT province     (#PCDATA)>
<!ELEMENT postal       (#PCDATA)>
<!ELEMENT country      (#PCDATA)>
<!ELEMENT e-mail       (#PCDATA)>
<!ELEMENT phone        (#PCDATA)>
<!ELEMENT mobile       (#PCDATA)>
<!-- Keys and Headings -->
<!ELEMENT heading      (#PCDATA)>
<!ELEMENT key          (#PCDATA)>
<!ELEMENT value        (#PCDATA)>
<!-- Date and Time -->
<!ELEMENT year         (#PCDATA)>
<!ELEMENT month        (#PCDATA)>
<!ELEMENT day          (#PCDATA)>
<!ELEMENT hour         (#PCDATA)>
<!ELEMENT minute       (#PCDATA)>
<!ELEMENT second       (#PCDATA)>
<!-- Descriptive Elements -->
<!ELEMENT position     (#PCDATA)>
<!ELEMENT product      (#PCDATA)>
<!ELEMENT degree       (#PCDATA)>
<!ELEMENT course       (#PCDATA)>
<!ELEMENT author       (#PCDATA)>
<!ELEMENT publisher    (#PCDATA)>
<!ELEMENT subject      (#PCDATA)>
<!ELEMENT isbn         (#PCDATA)>
<!-- deprecated -->
<!ELEMENT deprecated   (#PCDATA)>
<!-- Compound Elements -->
<!-- Compound Time -->
<!ELEMENT date         (year?,(month,day?)?,(hour,(minute,second?)?)?)>
<!ELEMENT from         (date)>
<!ELEMENT to           (date)>
<!ELEMENT period       ((from,to)|date)>
<!-- Simple Compound Elements -->
<!ELEMENT address      ((street,apartment?)?,city?,(state|province)?,postal?,country?,e-mail?,phone?,mobile?)>
<!ELEMENT book         (name,author*,(address?,publisher)?,date?,subject?,isbn?)>
  <!ATTLIST book         name         ID           #IMPLIED>
<!ELEMENT institution  (name,oldname*,address?)>
  <!ATTLIST institution  name         ID           #IMPLIED>
  <!ATTLIST institution  url          CDATA        #IMPLIED>
  <!ATTLIST institution  deprecated   (true|false) "false">
<!-- Reference Elements -->
<!ELEMENT bookref      EMPTY>
<!ATTLIST bookref      ref          IDREF        #REQUIRED>
<!ELEMENT instref      EMPTY>
<!ATTLIST instref      ref          IDREF        #REQUIRED>
<!-- Simple Compound Markups -->
<!ELEMENT buzzword     (#PCDATA|deprecated)*>
  <!ATTLIST buzzword     deprecated   (true|false) "false">
  <!ATTLIST buzzword     url          CDATA        #IMPLIED>
<!ELEMENT language     (#PCDATA)>
  <!ATTLIST language     level        (native|fluent|conversational|good|fair|poor) #REQUIRED>
  <!ATTLIST language     deprecated   (true|false) "false">
<!-- Hashing Elements -->
<!-- Should I make the Key and Attribute?? -->
<!ELEMENT status       (key,value)>
  <!ATTLIST status       spanning     (true|false) "false">
<!ELEMENT skill        (key,(buzzword*|language*))>
  <!ATTLIST skill        deprecated   (true|false) "false">
<!ELEMENT curriculum   (key?,course*)>
  <!ATTLIST curriculum   deprecated   (true|false) "false">
<!-- Compound Text Elements -->
<!ELEMENT tools        (buzzword*)>
<!ELEMENT task         (#PCDATA|buzzword|instref)*>
<!ELEMENT interest     (#PCDATA|buzzword|bookref|instref|deprecated)*>
  <!ATTLIST interest     url          CDATA        #IMPLIED>
<!ELEMENT para         (#PCDATA|buzzword|product|instref|deprecated)*>
<!-- Compound Paragraph Elements -->
<!ELEMENT objective    (para*)>
<!ELEMENT summary      (para*,task*)>
<!ELEMENT achievement  (tools?,para*)>
<!-- Complex Compound Elements -->
<!ELEMENT title        (name,oldname*,address)>
<!ELEMENT bibliography (heading?,book*,institution*)>
  <!ATTLIST bibliography deprecated   (true|false) "false">
<!ELEMENT job          (institution,period,position?,achievement*)>
  <!ATTLIST job          deprecated   (true|false) "false">
<!ELEMENT school       (institution,period?,degree,achievement*,curriculum*)>
  <!ATTLIST school       deprecated   (true|false) "false">
<!ELEMENT reference    (name,(position,instref?)?,e-mail?,phone?,mobile?)>
  <!ATTLIST reference    deprecated   (true|false) "false">
<!ELEMENT section      (heading,(objective|status*|summary|skill*|job*|school*|interest*|reference*))>
  <!ATTLIST section      deprecated   (true|false) "false">
<!-- Top Level Tag -->
<!ELEMENT resume       (title,bibliography?,section*)>
  <!ATTLIST resume       url          CDATA        #IMPLIED>

Résumé.dtd, the Résumé Document Type Definition

These days, most DTDs have been thrown by the wayside in favor of XML defining itself through an XML Schema. A few years ago, I upgraded my DTD to a Schema to make it more compatible with common XML editors—though I’ve yet to find a descent (Xmplify was a total failure in that respect with no ability to context-complete based on an associated scheme).

<?xml version="1.0" encoding="UTF-8"?>
<!-- Character Entities -->
<!DOCTYPE xs:schema [
  <!ENTITY  nbsp         "&#x00A0;">
  <!ENTITY  chi2         "&#x03C7;&#x00B2;">
  <!ENTITY  endash       "&#x2013;">
  <!ENTITY  eacute       "&#x00E9;">
]>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.timehorse.com"
           xmlns="http://www.timehorse.com"
           elementFormDefault="qualified">

  <!-- Common Attributes -->
  <xs:attribute name="url" type="xs:anyURI"/>
  <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
  <xs:attribute name="spanning" type="xs:boolean" default="false"/>
  <xs:attribute name="name" type="xs:string"/>
  <xs:attribute name="ref" type="xs:string"/>
  <xs:attribute name="level">
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:enumeration value="native"/>
        <xs:enumeration value="fluent"/>
        <xs:enumeration value="conversational"/>
        <xs:enumeration value="good"/>
        <xs:enumeration value="fair"/>
        <xs:enumeration value="poor"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>

  <!-- Attribute Groupings -->
  <xs:attributeGroup name="depricatedUrlGroup">
    <xs:attribute ref="url"/>
    <xs:attribute ref="deprecated"/>
  </xs:attributeGroup>

  <!-- Simple Types -->
  <!-- Names and Addresses -->
  <xs:element name="name" type="xs:string"/> <!-- nameType -->
  <xs:element name="oldname" type="xs:string"/> <!-- nameType -->
  <xs:element name="street" type="xs:string"/>
  <xs:element name="city" type="xs:string"/> <!-- nameType -->
  <xs:element name="state" type="xs:string"/> <!-- regionType -->
  <xs:element name="province" type="xs:string"/> <!-- regionType -->
  <xs:element name="postal" type="xs:string"/> <!-- postalType -->
  <xs:element name="country" type="xs:string"/>
  <xs:element name="e-mail" type="xs:string"/> <!-- emailType -->
  <xs:element name="phone" type="phoneType"/>
  <xs:element name="mobile" type="phoneType"/>

  <!-- Keys and Headings -->
  <xs:element name="heading" type="xs:string"/>
  <xs:element name="key" type="xs:string"/>
  <xs:element name="value" type="xs:string"/>

  <!-- Date and Time -->
  <xs:element name="year" type="xs:gYear"/>
  <xs:element name="month" type="monthType"/>
  <xs:element name="day" type="dayType"/>
  <xs:element name="hour" type="hourType"/>
  <xs:element name="minute" type="minuteType"/>
  <xs:element name="second" type="secondType"/>

  <!-- Descriptive Elements -->
  <xs:element name="position" type="xs:string"/>
  <xs:element name="product" type="xs:string"/>
  <xs:element name="degree" type="xs:string"/>
  <xs:element name="course" type="xs:string"/>
  <xs:element name="author" type="xs:string"/> <!-- nameType -->
  <xs:element name="publisher" type="xs:string"/>
  <xs:element name="subject" type="xs:string"/>
  <xs:element name="isbn" type="isbnType"/>

  <!-- Deprecated -->
  <xs:element name="deprecated" type="xs:string"/>

  <!-- Complex, Text-Only -->
  <xs:element name="apartment">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="spellout" type="xs:boolean" default="false"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <!-- Empty Elements (markers) -->
  <xs:element name="author-et-al">
    <xs:complexType>
      <xs:complexContent>
        <xs:restriction base="xs:anyType"/>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>

  <!-- Compound Elements -->
  <!-- Compound Time -->
  <xs:element name="date">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="year" minOccurs="0" maxOccurs="1"/>
        <xs:sequence minOccurs="0">
          <xs:element ref="month" minOccurs="1" maxOccurs="1"/>
          <xs:element ref="day" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:sequence minOccurs="0">
          <xs:element ref="hour" minOccurs="1" maxOccurs="1"/>
          <xs:sequence minOccurs="0">
            <xs:element ref="minute" minOccurs="1" maxOccurs="1"/>
            <xs:element ref="second" minOccurs="0" maxOccurs="1"/>
          </xs:sequence>
        </xs:sequence>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="from">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="date" minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="to">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="date" minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="period">
    <xs:complexType>
      <xs:choice>
        <xs:sequence>
          <xs:element ref="from" minOccurs="1" maxOccurs="1"/>
          <xs:element ref="to" minOccurs="1" maxOccurs="1"/>
        </xs:sequence>
        <xs:element ref="date"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <!-- Simple Compound Elements -->
  <xs:element name="address">
    <xs:complexType>
      <xs:sequence>
        <xs:sequence minOccurs="0">
          <xs:element ref="street" minOccurs="1" maxOccurs="1"/>
          <xs:element ref="apartment" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:element ref="city" minOccurs="0" maxOccurs="1"/>
        <xs:choice minOccurs="0">
          <xs:element ref="state"/>
          <xs:element ref="province"/>
        </xs:choice>
        <xs:element ref="postal" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="country" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="e-mail" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="phone" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="mobile" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="book">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="name" minOccurs="1" maxOccurs="1"/>
        <xs:sequence minOccurs="0">
          <xs:element ref="author" minOccurs="1" maxOccurs="unbounded"/>
          <xs:element ref="author-et-al" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:sequence minOccurs="0">
          <xs:element ref="address" minOccurs="0" maxOccurs="1"/>
          <xs:element ref="publisher" minOccurs="1" maxOccurs="1"/>
        </xs:sequence>
        <xs:element ref="date" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="subject" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="isbn" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string"/>
      <xs:attribute name="url" type="xs:anyURI"/>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="institution">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="name" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="oldname" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="address" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string"/>
      <xs:attribute name="url" type="xs:anyURI"/>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>

  <!-- Reference Elements -->
  <xs:element name="bookref">
    <xs:complexType>
      <xs:attribute name="ref" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="instref">
    <xs:complexType>
      <xs:attribute name="ref" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>

  <!-- Simple Compound Markups -->
  <xs:element name="buzzword">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:element ref="deprecated" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="url" type="xs:anyURI"/>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="language">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="level">
            <xs:simpleType>
              <xs:restriction base="xs:string">
                <xs:enumeration value="native"/>
                <xs:enumeration value="fluent"/>
                <xs:enumeration value="conversational"/>
                <xs:enumeration value="good"/>
                <xs:enumeration value="fair"/>
                <xs:enumeration value="poor"/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
          <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <!-- Hashing Elements -->
  <!-- Note: Should I make the Key and Attributes?? -->
  <xs:element name="status">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="key" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="value" minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="spanning" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="skill">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="key" minOccurs="1" maxOccurs="1"/>
        <xs:choice>
          <xs:element ref="buzzword" minOccurs="0"
                      maxOccurs="unbounded"/>
          <xs:element ref="language" minOccurs="0"
                      maxOccurs="unbounded"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="curriculum">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="key" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="course" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>

  <!-- Compound Text Elements -->
  <xs:element name="tools">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="buzzword" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="task">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="buzzword"/>
        <xs:element ref="instref"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="interest">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="buzzword"/>
        <xs:element ref="bookref"/>
        <xs:element ref="instref"/>
        <xs:element ref="deprecated"/>
      </xs:choice>
      <xs:attribute name="url" type="xs:anyURI"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="para">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="buzzword"/>
        <xs:element ref="product"/>
        <xs:element ref="instref"/>
        <xs:element ref="deprecated"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <!-- Compound Paragraph Elements -->
  <xs:element name="objective">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="para" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="summary">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="para" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="task" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="achievement">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="tools" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="para" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- Complex Compound Elements -->
  <xs:element name="title">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="name" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="oldname" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="address" minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="bibliography">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="heading" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="book" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="institution" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="job">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="institution" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="period" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="position" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="achievement" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="school">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="institution" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="period" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="degree" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="achievement" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="curriculum" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="reference">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="name" minOccurs="1" maxOccurs="1"/>
        <xs:sequence minOccurs="0" maxOccurs="1">
          <xs:element ref="position" minOccurs="1" maxOccurs="1"/>
          <xs:element ref="instref" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:element ref="e-mail" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="phone" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="mobile" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="section">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="heading" minOccurs="1" maxOccurs="1"/>
        <xs:choice>
          <xs:element ref="objective" minOccurs="0" maxOccurs="unbounded"/>
          <xs:element ref="status" maxOccurs="unbounded"/>
          <xs:element ref="summary" minOccurs="0" maxOccurs="unbounded"/>
          <xs:element ref="skill" maxOccurs="unbounded"/>
          <xs:element ref="job" maxOccurs="unbounded"/>
          <xs:element ref="school" maxOccurs="unbounded"/>
          <xs:element ref="interest" maxOccurs="unbounded"/>
          <xs:element ref="reference" maxOccurs="unbounded"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="deprecated" type="xs:boolean" default="false"/>
    </xs:complexType>
  </xs:element>

  <!-- Top Level Tag -->
  <xs:element name="resume">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="title" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="bibliography" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="section" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="url" type="xs:anyURI"/>
    </xs:complexType>
  </xs:element>

  <!-- Simple Patern-based Types -->
  <xs:simpleType name="phoneType">
    <xs:restriction base="xs:string">
      <xs:pattern
          value="(\+[1-9][0-9]{0,2} )?(\([1-9][0-9]*\) )?[#*1-9][-#*0-9.pw]*(x[#*0-9.pw]+)?"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="postalType">
    <xs:restriction base="xs:string">
      <xs:pattern value="([0-9]{5}(-[0-9]{4})?|[0-9A-Z]{3} [0-9A-Z]{3}|[0-9]+)"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="regionType">
    <xs:restriction base="xs:string">
      <xs:pattern value="[A-Z]([A-Z]|[a-zé]*( [A-Z][a-zé]*)?)"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="emailType">
    <xs:restriction base="xs:string">
      <xs:pattern
          value="[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+([A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="nameType">
    <xs:restriction base="xs:string">
      <xs:pattern value="[A-Z]([a-z']*|\.)( [A-Z]([a-z']*|\.))*"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="monthType">
    <xs:restriction base="xs:string">
      <xs:pattern value="([A-Z][a-z]*|0?[1-9]|1[0-2])*"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="dayType">
    <xs:restriction base="xs:string">
      <xs:pattern value="(0?[1-9]|[12][0-9]|30|31)"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="hourType">
    <xs:restriction base="xs:string">
      <xs:pattern value="([01]?[0-9]|2[0-3])"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="minuteType">
    <xs:restriction base="xs:string">
      <xs:pattern value="(0?[1-9]|[1-5][0-9]|60)"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="secondType">
    <xs:restriction base="xs:string">
      <xs:pattern value="(0?[1-9]|[1-5][0-9]|6[01])"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="isbnType">
    <xs:restriction base="xs:string">
      <xs:pattern value="[- 0-9]{9,}"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

Résumé.xsd, the Résumé XML Schema

One thing of note is the concept of deprecated. Not everything in my Résumé is relevant to today. I like keeping the older elements in the document but when a skill or position becomes no longer relevant to the current job market, it’s marked for deprecation and won’t appear in the final form. How that’s done will be explained in Part 2: Converting to HTML.

With the DTD and XML Schema, I was able to at least verify my Résumé was compliant and ready for publication. And, as always, I am most assuredly available for hire even with my older Résumé.

One Reply to “Dusting off the Résumé, Part 1: The Schema”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.