# RELAX NG Schema for vCard in XML
# Extract from RFC6351.
# Erratum 2994 applied.
# Erratum 3047 applied.
# Erratum 3008 applied.
# Erratum 4247 applied.
default namespace = "urn:ietf:params:xml:ns:vcard-4.0"
### Section 3.3: vCard Format Specification
#
# 3.3
iana-token = xsd:string { pattern = "[a-zA-Z0-9\-]+" }
x-name = xsd:string { pattern = "x-[a-zA-Z0-9\-]+" }
### Section 4: Value types
#
# 4.1
value-text = element text { text }
value-text-list = value-text+
# 4.2
value-uri = element uri { xsd:anyURI }
# 4.3.1
value-date = element date {
xsd:string { pattern = "\d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d" }
}
# 4.3.2
value-time = element time {
xsd:string { pattern = "(\d\d(\d\d(\d\d)?)?|-\d\d(\d\d)?|--\d\d)"
~ "(Z|[+\-]\d\d(\d\d)?)?" }
}
# 4.3.3
value-date-time = element date-time {
xsd:string { pattern = "(\d{8}|--\d{4}|---\d\d)T\d\d(\d\d(\d\d)?)?"
~ "(Z|[+\-]\d\d(\d\d)?)?" }
}
# 4.3.4
value-date-and-or-time = value-date | value-date-time | value-time
# 4.3.5
value-timestamp = element timestamp {
xsd:string { pattern = "\d{8}T\d{6}(Z|[+\-]\d\d(\d\d)?)?" }
}
# 4.4
value-boolean = element boolean { xsd:boolean }
# 4.5
value-integer = element integer { xsd:integer }
# 4.6
value-float = element float { xsd:float }
# 4.7
value-utc-offset = element utc-offset {
xsd:string { pattern = "[+\-]\d\d(\d\d)?" }
}
# 4.8
value-language-tag = element language-tag {
xsd:string { pattern = "([a-z]{2,3}((-[a-z]{3}){0,3})?|[a-z]{4,8})"
~ "(-[a-z]{4})?(-([a-z]{2}|\d{3}))?"
~ "(-([0-9a-z]{5,8}|\d[0-9a-z]{3}))*"
~ "(-[0-9a-wyz](-[0-9a-z]{2,8})+)*"
~ "(-x(-[0-9a-z]{1,8})+)?|x(-[0-9a-z]{1,8})+|"
~ "[a-z]{1,3}(-[0-9a-z]{2,8}){1,2}" }
}
### Section 5: Parameters
#
# 5.1
param-language = element language { value-language-tag }?
# 5.2
param-pref = element pref {
element integer {
xsd:integer { minInclusive = "1" maxInclusive = "100" }
}
}?
# 5.4
param-altid = element altid { value-text }?
# 5.5
param-pid = element pid {
element text { xsd:string { pattern = "\d+(\.\d+)?" } }+
}?
# 5.6
param-type = element type { element text { "work" | "home" }+ }?
# 5.7
param-mediatype = element mediatype { value-text }?
# 5.8
param-calscale = element calscale { element text { "gregorian" } }?
# 5.9
param-sort-as = element sort-as { value-text+ }?
# 5.10
param-geo = element geo { value-uri }?
# 5.11
param-tz = element tz { value-text | value-uri }?
### Section 6: Properties
#
# 6.1.3
property-source = element source {
element parameters { param-altid, param-pid, param-pref,
param-mediatype }?,
value-uri
}
# 6.1.4
property-kind = element kind {
element text { "individual" | "group" | "org" | "location" |
x-name | iana-token }*
}
# 6.2.1
property-fn = element fn {
element parameters { param-language, param-altid, param-pid,
param-pref, param-type }?,
value-text
}
# 6.2.2
property-n = element n {
element parameters { param-language, param-sort-as, param-altid }?,
element surname { text }+,
element given { text }+,
element additional { text }+,
element prefix { text }+,
element suffix { text }+
}
# 6.2.3
property-nickname = element nickname {
element parameters { param-language, param-altid, param-pid,
param-pref, param-type }?,
value-text-list
}
# 6.2.4
property-photo = element photo {
element parameters { param-altid, param-pid, param-pref, param-type,
param-mediatype }?,
value-uri
}
# 6.2.5
property-bday = element bday {
element parameters { param-altid, param-calscale }?,
(value-date-and-or-time | value-text)
}
# 6.2.6
property-anniversary = element anniversary {
element parameters { param-altid, param-calscale }?,
(value-date-and-or-time | value-text)
}
# 6.2.7
property-gender = element gender {
element sex { "" | "M" | "F" | "O" | "N" | "U" },
element identity { text }?
}
# 6.3.1
param-label = element label { value-text }?
property-adr = element adr {
element parameters { param-language, param-altid, param-pid,
param-pref, param-type, param-geo, param-tz,
param-label }?,
element pobox { text }+,
element ext { text }+,
element street { text }+,
element locality { text }+,
element region { text }+,
element code { text }+,
element country { text }+
}
# 6.4.1
property-tel = element tel {
element parameters {
param-altid,
param-pid,
param-pref,
element type {
element text { "work" | "home" | "text" | "voice"
| "fax" | "cell" | "video" | "pager"
| "textphone" | x-name | iana-token }+
}?,
param-mediatype
}?,
(value-text | value-uri)
}
# 6.4.2
property-email = element email {
element parameters { param-altid, param-pid, param-pref,
param-type }?,
value-text
}
# 6.4.3
property-impp = element impp {
element parameters { param-altid, param-pid, param-pref,
param-type, param-mediatype }?,
value-uri
}
# 6.4.4
property-lang = element lang {
element parameters { param-altid, param-pid, param-pref,
param-type }?,
value-language-tag
}
# 6.5.1
property-tz = element tz {
element parameters { param-altid, param-pid, param-pref,
param-type, param-mediatype }?,
(value-text | value-uri | value-utc-offset)
}
# 6.5.2
property-geo = element geo {
element parameters { param-altid, param-pid, param-pref,
param-type, param-mediatype }?,
value-uri
}
# 6.6.1
property-title = element title {
element parameters { param-language, param-altid, param-pid,
param-pref, param-type }?,
value-text
}
# 6.6.2
property-role = element role {
element parameters { param-language, param-altid, param-pid,
param-pref, param-type }?,
value-text
}
# 6.6.3
property-logo = element logo {
element parameters { param-language, param-altid, param-pid,
param-pref, param-type, param-mediatype }?,
value-uri
}
# 6.6.4
property-org = element org {
element parameters { param-language, param-altid, param-pid,
param-pref, param-type, param-sort-as }?,
value-text-list
}
# 6.6.5
property-member = element member {
element parameters { param-altid, param-pid, param-pref,
param-mediatype }?,
value-uri
}
# 6.6.6
property-related = element related {
element parameters {
param-altid,
param-pid,
param-pref,
element type {
element text {
"work" | "home" | "contact" | "acquaintance" |
"friend" | "met" | "co-worker" | "colleague" | "co-resident" |
"neighbor" | "child" | "parent" | "sibling" | "spouse" |
"kin" | "muse" | "crush" | "date" | "sweetheart" | "me" |
"agent" | "emergency"
}+
}?,
param-mediatype
}?,
(value-uri | value-text)
}
# 6.7.1
property-categories = element categories {
element parameters { param-altid, param-pid, param-pref,
param-type }?,
value-text-list
}
# 6.7.2
property-note = element note {
element parameters { param-language, param-altid, param-pid,
param-pref, param-type }?,
value-text
}
# 6.7.3
property-prodid = element prodid { value-text }
# 6.7.4
property-rev = element rev { value-timestamp }
# 6.7.5
property-sound = element sound {
element parameters { param-language, param-altid, param-pid,
param-pref, param-type, param-mediatype }?,
value-uri
}
# 6.7.6
property-uid = element uid { value-uri }
# 6.7.7
property-clientpidmap = element clientpidmap {
element sourceid { xsd:positiveInteger },
value-uri
}
# 6.7.8
property-url = element url {
element parameters { param-altid, param-pid, param-pref,
param-type, param-mediatype }?,
value-uri
}
# 6.8.1
property-key = element key {
element parameters { param-altid, param-pid, param-pref,
param-type, param-mediatype }?,
(value-uri | value-text)
}
# 6.9.1
property-fburl = element fburl {
element parameters { param-altid, param-pid, param-pref,
param-type, param-mediatype }?,
value-uri
}
# 6.9.2
property-caladruri = element caladruri {
element parameters { param-altid, param-pid, param-pref,
param-type, param-mediatype }?,
value-uri
}
# 6.9.3
property-caluri = element caluri {
element parameters { param-altid, param-pid, param-pref,
param-type, param-mediatype }?,
value-uri
}
# Top-level grammar
property = property-adr | property-anniversary | property-bday
| property-caladruri | property-caluri | property-categories
| property-clientpidmap | property-email | property-fburl
| property-fn | property-geo | property-impp | property-key
| property-kind | property-lang | property-logo
| property-member | property-n | property-nickname
| property-note | property-org | property-photo
| property-prodid | property-related | property-rev
| property-role | property-gender | property-sound
| property-source | property-tel | property-title
| property-tz | property-uid | property-url
start = element vcards {
element vcard {
(property
| element group {
attribute name { text },
property*
})+
}+
}