1# RELAX NG Schema for vCard in XML 2# Extract from RFC6351. 3# Erratum 2994 applied. 4# Erratum 3047 applied. 5# Erratum 3008 applied. 6# Erratum 4247 applied. 7 8default namespace = "urn:ietf:params:xml:ns:vcard-4.0" 9 10### Section 3.3: vCard Format Specification 11# 12# 3.3 13iana-token = xsd:string { pattern = "[a-zA-Z0-9\-]+" } 14x-name = xsd:string { pattern = "x-[a-zA-Z0-9\-]+" } 15 16### Section 4: Value types 17# 18# 4.1 19value-text = element text { text } 20value-text-list = value-text+ 21 22# 4.2 23value-uri = element uri { xsd:anyURI } 24 25# 4.3.1 26value-date = element date { 27 xsd:string { pattern = "\d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d" } 28 } 29 30# 4.3.2 31value-time = element time { 32 xsd:string { pattern = "(\d\d(\d\d(\d\d)?)?|-\d\d(\d\d)?|--\d\d)" 33 ~ "(Z|[+\-]\d\d(\d\d)?)?" } 34 } 35 36# 4.3.3 37value-date-time = element date-time { 38 xsd:string { pattern = "(\d{8}|--\d{4}|---\d\d)T\d\d(\d\d(\d\d)?)?" 39 ~ "(Z|[+\-]\d\d(\d\d)?)?" } 40 } 41 42# 4.3.4 43value-date-and-or-time = value-date | value-date-time | value-time 44 45# 4.3.5 46value-timestamp = element timestamp { 47 xsd:string { pattern = "\d{8}T\d{6}(Z|[+\-]\d\d(\d\d)?)?" } 48 } 49 50# 4.4 51value-boolean = element boolean { xsd:boolean } 52 53# 4.5 54value-integer = element integer { xsd:integer } 55 56# 4.6 57value-float = element float { xsd:float } 58 59# 4.7 60value-utc-offset = element utc-offset { 61 xsd:string { pattern = "[+\-]\d\d(\d\d)?" } 62 } 63 64# 4.8 65value-language-tag = element language-tag { 66 xsd:string { pattern = "([a-z]{2,3}((-[a-z]{3}){0,3})?|[a-z]{4,8})" 67 ~ "(-[a-z]{4})?(-([a-z]{2}|\d{3}))?" 68 ~ "(-([0-9a-z]{5,8}|\d[0-9a-z]{3}))*" 69 ~ "(-[0-9a-wyz](-[0-9a-z]{2,8})+)*" 70 ~ "(-x(-[0-9a-z]{1,8})+)?|x(-[0-9a-z]{1,8})+|" 71 ~ "[a-z]{1,3}(-[0-9a-z]{2,8}){1,2}" } 72 } 73 74### Section 5: Parameters 75# 76# 5.1 77param-language = element language { value-language-tag }? 78 79# 5.2 80param-pref = element pref { 81 element integer { 82 xsd:integer { minInclusive = "1" maxInclusive = "100" } 83 } 84 }? 85 86# 5.4 87param-altid = element altid { value-text }? 88 89# 5.5 90param-pid = element pid { 91 element text { xsd:string { pattern = "\d+(\.\d+)?" } }+ 92 }? 93 94# 5.6 95param-type = element type { element text { "work" | "home" }+ }? 96 97# 5.7 98param-mediatype = element mediatype { value-text }? 99 100# 5.8 101param-calscale = element calscale { element text { "gregorian" } }? 102 103# 5.9 104param-sort-as = element sort-as { value-text+ }? 105 106# 5.10 107param-geo = element geo { value-uri }? 108 109# 5.11 110param-tz = element tz { value-text | value-uri }? 111 112### Section 6: Properties 113# 114# 6.1.3 115property-source = element source { 116 element parameters { param-altid, param-pid, param-pref, 117 param-mediatype }?, 118 value-uri 119 } 120 121# 6.1.4 122property-kind = element kind { 123 element text { "individual" | "group" | "org" | "location" | 124 x-name | iana-token }* 125 } 126 127# 6.2.1 128property-fn = element fn { 129 element parameters { param-language, param-altid, param-pid, 130 param-pref, param-type }?, 131 value-text 132 } 133 134# 6.2.2 135property-n = element n { 136 element parameters { param-language, param-sort-as, param-altid }?, 137 element surname { text }+, 138 element given { text }+, 139 element additional { text }+, 140 element prefix { text }+, 141 element suffix { text }+ 142 } 143 144# 6.2.3 145property-nickname = element nickname { 146 element parameters { param-language, param-altid, param-pid, 147 param-pref, param-type }?, 148 value-text-list 149 } 150 151# 6.2.4 152property-photo = element photo { 153 element parameters { param-altid, param-pid, param-pref, param-type, 154 param-mediatype }?, 155 value-uri 156 } 157 158# 6.2.5 159property-bday = element bday { 160 element parameters { param-altid, param-calscale }?, 161 (value-date-and-or-time | value-text) 162 } 163 164# 6.2.6 165property-anniversary = element anniversary { 166 element parameters { param-altid, param-calscale }?, 167 (value-date-and-or-time | value-text) 168 } 169 170# 6.2.7 171property-gender = element gender { 172 element sex { "" | "M" | "F" | "O" | "N" | "U" }, 173 element identity { text }? 174 } 175 176# 6.3.1 177param-label = element label { value-text }? 178property-adr = element adr { 179 element parameters { param-language, param-altid, param-pid, 180 param-pref, param-type, param-geo, param-tz, 181 param-label }?, 182 element pobox { text }+, 183 element ext { text }+, 184 element street { text }+, 185 element locality { text }+, 186 element region { text }+, 187 element code { text }+, 188 element country { text }+ 189 } 190 191# 6.4.1 192property-tel = element tel { 193 element parameters { 194 param-altid, 195 param-pid, 196 param-pref, 197 element type { 198 element text { "work" | "home" | "text" | "voice" 199 | "fax" | "cell" | "video" | "pager" 200 | "textphone" | x-name | iana-token }+ 201 }?, 202 param-mediatype 203 }?, 204 (value-text | value-uri) 205 } 206 207# 6.4.2 208property-email = element email { 209 element parameters { param-altid, param-pid, param-pref, 210 param-type }?, 211 value-text 212 } 213 214# 6.4.3 215property-impp = element impp { 216 element parameters { param-altid, param-pid, param-pref, 217 param-type, param-mediatype }?, 218 value-uri 219 } 220 221# 6.4.4 222property-lang = element lang { 223 element parameters { param-altid, param-pid, param-pref, 224 param-type }?, 225 value-language-tag 226 } 227 228# 6.5.1 229property-tz = element tz { 230 element parameters { param-altid, param-pid, param-pref, 231 param-type, param-mediatype }?, 232 (value-text | value-uri | value-utc-offset) 233 } 234 235# 6.5.2 236property-geo = element geo { 237 element parameters { param-altid, param-pid, param-pref, 238 param-type, param-mediatype }?, 239 value-uri 240 } 241 242# 6.6.1 243property-title = element title { 244 element parameters { param-language, param-altid, param-pid, 245 param-pref, param-type }?, 246 value-text 247 } 248 249# 6.6.2 250property-role = element role { 251 element parameters { param-language, param-altid, param-pid, 252 param-pref, param-type }?, 253 value-text 254 } 255 256# 6.6.3 257property-logo = element logo { 258 element parameters { param-language, param-altid, param-pid, 259 param-pref, param-type, param-mediatype }?, 260 value-uri 261 } 262 263# 6.6.4 264property-org = element org { 265 element parameters { param-language, param-altid, param-pid, 266 param-pref, param-type, param-sort-as }?, 267 value-text-list 268 } 269 270# 6.6.5 271property-member = element member { 272 element parameters { param-altid, param-pid, param-pref, 273 param-mediatype }?, 274 value-uri 275 } 276 277# 6.6.6 278property-related = element related { 279 element parameters { 280 param-altid, 281 param-pid, 282 param-pref, 283 element type { 284 element text { 285 "work" | "home" | "contact" | "acquaintance" | 286 "friend" | "met" | "co-worker" | "colleague" | "co-resident" | 287 "neighbor" | "child" | "parent" | "sibling" | "spouse" | 288 "kin" | "muse" | "crush" | "date" | "sweetheart" | "me" | 289 "agent" | "emergency" 290 }+ 291 }?, 292 param-mediatype 293 }?, 294 (value-uri | value-text) 295 } 296 297# 6.7.1 298property-categories = element categories { 299 element parameters { param-altid, param-pid, param-pref, 300 param-type }?, 301 value-text-list 302 } 303 304# 6.7.2 305property-note = element note { 306 element parameters { param-language, param-altid, param-pid, 307 param-pref, param-type }?, 308 value-text 309 } 310 311# 6.7.3 312property-prodid = element prodid { value-text } 313 314# 6.7.4 315property-rev = element rev { value-timestamp } 316 317# 6.7.5 318property-sound = element sound { 319 element parameters { param-language, param-altid, param-pid, 320 param-pref, param-type, param-mediatype }?, 321 value-uri 322 } 323 324# 6.7.6 325property-uid = element uid { value-uri } 326 327# 6.7.7 328property-clientpidmap = element clientpidmap { 329 element sourceid { xsd:positiveInteger }, 330 value-uri 331 } 332 333# 6.7.8 334property-url = element url { 335 element parameters { param-altid, param-pid, param-pref, 336 param-type, param-mediatype }?, 337 value-uri 338 } 339 340# 6.8.1 341property-key = element key { 342 element parameters { param-altid, param-pid, param-pref, 343 param-type, param-mediatype }?, 344 (value-uri | value-text) 345 } 346 347# 6.9.1 348property-fburl = element fburl { 349 element parameters { param-altid, param-pid, param-pref, 350 param-type, param-mediatype }?, 351 value-uri 352 } 353 354# 6.9.2 355property-caladruri = element caladruri { 356 element parameters { param-altid, param-pid, param-pref, 357 param-type, param-mediatype }?, 358 value-uri 359 } 360 361# 6.9.3 362property-caluri = element caluri { 363 element parameters { param-altid, param-pid, param-pref, 364 param-type, param-mediatype }?, 365 value-uri 366 } 367 368# Top-level grammar 369property = property-adr | property-anniversary | property-bday 370 | property-caladruri | property-caluri | property-categories 371 | property-clientpidmap | property-email | property-fburl 372 | property-fn | property-geo | property-impp | property-key 373 | property-kind | property-lang | property-logo 374 | property-member | property-n | property-nickname 375 | property-note | property-org | property-photo 376 | property-prodid | property-related | property-rev 377 | property-role | property-gender | property-sound 378 | property-source | property-tel | property-title 379 | property-tz | property-uid | property-url 380start = element vcards { 381 element vcard { 382 (property 383 | element group { 384 attribute name { text }, 385 property* 386 })+ 387 }+ 388 } 389