< draft-newton-json-content-rules-08.txt   draft-newton-json-content-rules-09.txt >
Network Working Group A. Newton Network Working Group A. Newton
Internet-Draft ARIN Internet-Draft ARIN
Intended status: Standards Track P. Cordell Intended status: Standards Track P. Cordell
Expires: September 29, 2017 Codalogic Expires: April 1, 2018 Codalogic
March 28, 2017 September 28, 2017
A Language for Rules Describing JSON Content A Language for Rules Describing JSON Content
draft-newton-json-content-rules-08 draft-newton-json-content-rules-09
Abstract Abstract
This document describes a language for specifying and testing the This document describes a language for specifying and testing the
expected content of JSON structures found in JSON-using protocols, expected content of JSON structures found in JSON-using protocols,
software, and processes. software, and processes.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79. provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at http://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on September 29, 2017. This Internet-Draft will expire on April 1, 2018.
Copyright Notice Copyright Notice
Copyright (c) 2017 IETF Trust and the persons identified as the Copyright (c) 2017 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License. described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
skipping to change at page 2, line 43 skipping to change at page 2, line 43
5.2. ruleset-id . . . . . . . . . . . . . . . . . . . . . . . 27 5.2. ruleset-id . . . . . . . . . . . . . . . . . . . . . . . 27
5.3. import . . . . . . . . . . . . . . . . . . . . . . . . . 27 5.3. import . . . . . . . . . . . . . . . . . . . . . . . . . 27
6. Tips and Tricks . . . . . . . . . . . . . . . . . . . . . . . 28 6. Tips and Tricks . . . . . . . . . . . . . . . . . . . . . . . 28
6.1. Any Member with Any Value . . . . . . . . . . . . . . . . 28 6.1. Any Member with Any Value . . . . . . . . . . . . . . . . 28
6.2. Lists of Values . . . . . . . . . . . . . . . . . . . . . 29 6.2. Lists of Values . . . . . . . . . . . . . . . . . . . . . 29
6.3. Groups in Arrays . . . . . . . . . . . . . . . . . . . . 29 6.3. Groups in Arrays . . . . . . . . . . . . . . . . . . . . 29
6.4. Groups in Objects . . . . . . . . . . . . . . . . . . . . 30 6.4. Groups in Objects . . . . . . . . . . . . . . . . . . . . 30
6.5. Group Rules as Macros . . . . . . . . . . . . . . . . . . 31 6.5. Group Rules as Macros . . . . . . . . . . . . . . . . . . 31
6.6. Object Mixins . . . . . . . . . . . . . . . . . . . . . . 31 6.6. Object Mixins . . . . . . . . . . . . . . . . . . . . . . 31
6.7. Subordinate Dependencies . . . . . . . . . . . . . . . . 31 6.7. Subordinate Dependencies . . . . . . . . . . . . . . . . 31
7. ABNF Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 32 7. Implementation Status . . . . . . . . . . . . . . . . . . . . 32
8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 38 7.1. JCR Validator . . . . . . . . . . . . . . . . . . . . . . 32
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 38 7.2. Codalogic JCR Parser . . . . . . . . . . . . . . . . . . 33
9.1. Normative References . . . . . . . . . . . . . . . . . . 38 7.3. JCR Java . . . . . . . . . . . . . . . . . . . . . . . . 33
9.2. Infomative References . . . . . . . . . . . . . . . . . . 38 8. ABNF Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 33
Appendix A. Co-Constraints . . . . . . . . . . . . . . . . . . . 39 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 39
Appendix B. Testing Against JSON Content Rules . . . . . . . . . 39 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 39
B.1. Locally Overriding Rules . . . . . . . . . . . . . . . . 39 10.1. Normative References . . . . . . . . . . . . . . . . . . 39
B.2. Rule Callbacks . . . . . . . . . . . . . . . . . . . . . 40 10.2. Infomative References . . . . . . . . . . . . . . . . . 40
Appendix C. JCR Implementations . . . . . . . . . . . . . . . . 40 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Appendix D. Syntax Changes from -06 and -07 . . . . . . . . . . 41
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 41 Appendix A. Co-Constraints . . . . . . . . . . . . . . . . . . . 40
Appendix B. Testing Against JSON Content Rules . . . . . . . . . 41
B.1. Locally Overriding Rules . . . . . . . . . . . . . . . . 41
B.2. Rule Callbacks . . . . . . . . . . . . . . . . . . . . . 42
Appendix C. Changes from -07 and -08 . . . . . . . . . . . . . . 42
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 42
1. Introduction 1. Introduction
This document describes JSON Content Rules (JCR), a language for This document describes JSON Content Rules (JCR), a language for
specifying and testing the interchange of data in JSON [RFC7159] specifying and testing the interchange of data in JSON [RFC7159]
format used by computer protocols and processes. The syntax of JCR format used by computer protocols and processes. The syntax of JCR
is not JSON but is "JSON-like", possessing the conciseness and is not JSON but is "JSON-like", possessing the conciseness and
utility that has made JSON popular. utility that has made JSON popular.
1.1. A First Example: Specifying Content 1.1. A First Example: Specifying Content
skipping to change at page 5, line 9 skipping to change at page 5, line 9
$fn = "file-name" : "rfc4627.txt" $fn = "file-name" : "rfc4627.txt"
$lc = "line-count" : 2102 $lc = "line-count" : 2102
$wc = "word-count" : 16714 $wc = "word-count" : 16714
Figure 7 Figure 7
In this example, the protocol specification describes the JSON object In this example, the protocol specification describes the JSON object
in general and an implementation overrides the rules for testing in general and an implementation overrides the rules for testing
specific cases. specific cases.
All figures used in this specification are available here [1].
2. Overview of the Language 2. Overview of the Language
JCR is composed of rules (as the name suggests). A collection of JCR is composed of rules (as the name suggests). A collection of
rules that is processed together is a ruleset. Rulesets may also rules that is processed together is a ruleset. Rulesets may also
contain comments, blank lines, and directives that apply to the contain comments, blank lines, and directives that apply to the
processing of a ruleset. processing of a ruleset.
Rules are composed of two parts, an optional rule name and a rule Rules are composed of two parts, an optional rule name and a rule
specification. A rule specification can be either a type specification. A rule specification can be either a type
specification or a member specification. A member specification specification or a member specification. A member specification
skipping to change at page 32, line 19 skipping to change at page 32, line 19
; $referrer_uri can only be present if ; $referrer_uri can only be present if
; $location_uri is present ; $location_uri is present
{ ( $location_uri, $referrer_uri? )? } { ( $location_uri, $referrer_uri? )? }
$location_uri = "locationURI" : uri $location_uri = "locationURI" : uri
$referrer_uri = "referrerURI" : uri $referrer_uri = "referrerURI" : uri
Figure 69 Figure 69
7. ABNF Syntax 7. Implementation Status
This section records the status of known implementations of the
protocol defined by this specification at the time of posting of this
Internet-Draft, and is based on a proposal described in [RFC7492] .
The description of implementations in this section is intended to
assist the IETF in its decision processes in progressing drafts to
RFCs. Please note that the listing of any individual implementation
here does not imply endorsement by the IETF. Furthermore, no effort
has been spent to verify the information presented here that was
supplied by IETF contributors. This is not intended as, and must not
be construed to be, a catalog of available implementations or their
features. Readers are advised to note that other implementations may
exist.
According to [RFC7492] , "this will allow reviewers and working
groups to assign due consideration to documents that have the benefit
of running code, which may serve as evidence of valuable
experimentation and feedback that have made the implemented protocols
more mature. It is up to the individual working groups to use this
information as they see fit".
7.1. JCR Validator
The JCR Validator, written in Ruby, currently implements all portions
of this specification, and has been used extensively to prototype
various aspects of JCR under consideration. It's development has
gone hand-in-hand with this specification.
This software is primarily produced by the American Registry for
Internet Numbers (ARIN) and freely distributable under the ISC
license.
Source code for this software is available on GitHub at
<https://github.com/arineng/jcrvalidator>. This software is also
easily obtained as a Ruby Gem through the Ruby Gem system.
7.2. Codalogic JCR Parser
The Codalogic JCR Parser is a C++ implementation of a JCR parsing
engine, and is a work in progress. It is targeted for the Windows
platform.
This software is produced by Codalogic Ltd and freely distributable
under the Gnu LGPL v3 license.
Source code is availabe on GitHub at <https://github.com/codalogic/
cl-jcr-parser>.
7.3. JCR Java
JCR Java is a work in progress and currently only implements the
parsing of JCR rulesets according to the ABNF using a custom parsing
framework.
This software is produced by the American Registry for Internet
Numbers (ARIN) and freely distributable under the MIT license.
Source code is available on BitBucket at
<https://bitbucket.org/anewton_1998/jcr_java>.
8. ABNF Syntax
The following ABNF describes the syntax for JSON Content Rules. A The following ABNF describes the syntax for JSON Content Rules. A
text file containing these ABNF rules can be downloaded from text file containing these ABNF rules can be downloaded from
[JCR_ABNF]. [JCR_ABNF].
jcr = *( sp-cmt / directive / root-rule / rule ) jcr = *( sp-cmt / directive / root-rule / rule )
sp-cmt = spaces / comment
spaces = 1*( WSP / CR / LF )
DSPs = ; Directive spaces
1*WSP / ; When in one-line directive
1*sp-cmt ; When in muti-line directive
comment = ";" *comment-char comment-end-char
comment-char = HTAB / %x20-10FFFF
; Any char other than CR / LF
comment-end-char = CR / LF
directive = "#" (one-line-directive / multi-line-directive)
one-line-directive = [ DSPs ]
(directive-def / one-line-tbd-directive-d)
*WSP eol
multi-line-directive = "{" *sp-cmt
( directive-def /
multi-line-tbd-directive-d )
*sp-cmt "}"
directive-def = jcr-version-d / ruleset-id-d / import-d
jcr-version-d = jcr-version-kw DSPs major-version
"." minor-version
*( DSPs "+" [ DSPs ] extension-id )
major-version = non-neg-integer
minor-version = non-neg-integer
extension-id = ALPHA *not-space
ruleset-id-d = ruleset-id-kw DSPs ruleset-id
import-d = import-kw DSPs ruleset-id
[ DSPs as-kw DSPs ruleset-id-alias ]
ruleset-id = ALPHA *not-space
not-space = %x21-10FFFF
ruleset-id-alias = name
one-line-tbd-directive-d = directive-name
[ WSP one-line-directive-parameters ]
directive-name = name
one-line-directive-parameters = *not-eol
not-eol = HTAB / %x20-10FFFF
eol = CR / LF
multi-line-tbd-directive-d = directive-name
[ 1*sp-cmt multi-line-directive-parameters ]
multi-line-directive-parameters = multi-line-parameters
multi-line-parameters = *(comment / q-string / regex /
not-multi-line-special)
not-multi-line-special = spaces / %x21 / %x23-2E / %x30-3A /
%x3C-7C / %x7E-10FFFF ; not ", /, ; or }
root-rule = value-rule / group-rule sp-cmt = spaces / comment
spaces = 1*( WSP / CR / LF )
DSPs = ; Directive spaces
1*WSP / ; When in one-line directive
1*sp-cmt ; When in muti-line directive
comment = ";" *comment-char comment-end-char
comment-char = HTAB / %x20-10FFFF
; Any char other than CR / LF
comment-end-char = CR / LF
rule = annotations "$" rule-name *sp-cmt directive = "#" (one-line-directive / multi-line-directive)
"=" *sp-cmt rule-def one-line-directive = [ DSPs ]
(directive-def / one-line-tbd-directive-d)
*WSP eol
multi-line-directive = "{" *sp-cmt
( directive-def /
multi-line-tbd-directive-d )
*sp-cmt "}"
directive-def = jcr-version-d / ruleset-id-d / import-d
jcr-version-d = jcr-version-kw DSPs major-version
"." minor-version
*( DSPs "+" [ DSPs ] extension-id )
major-version = non-neg-integer
minor-version = non-neg-integer
extension-id = ALPHA *not-space
ruleset-id-d = ruleset-id-kw DSPs ruleset-id
import-d = import-kw DSPs ruleset-id
[ DSPs as-kw DSPs ruleset-id-alias ]
ruleset-id = ALPHA *not-space
not-space = %x21-10FFFF
ruleset-id-alias = name
one-line-tbd-directive-d = directive-name
[ WSP one-line-directive-parameters ]
directive-name = name
one-line-directive-parameters = *not-eol
not-eol = HTAB / %x20-10FFFF
eol = CR / LF
multi-line-tbd-directive-d = directive-name
[ 1*sp-cmt multi-line-directive-parameters ]
multi-line-directive-parameters = multi-line-parameters
multi-line-parameters = *(comment / q-string / regex /
not-multi-line-special)
not-multi-line-special = spaces / %x21 / %x23-2E / %x30-3A /
%x3C-7C / %x7E-10FFFF ; not ", /, ; or }
rule-name = name root-rule = value-rule / group-rule
target-rule-name = annotations "$"
[ ruleset-id-alias "." ]
rule-name
name = ALPHA *( ALPHA / DIGIT / "-" / "-" )
rule-def = member-rule / type-designator rule-def-type-rule / rule = annotations "$" rule-name *sp-cmt
array-rule / object-rule / group-rule / "=" *sp-cmt rule-def
target-rule-name
type-designator = type-kw 1*sp-cmt / ":" *sp-cmt
rule-def-type-rule = value-rule / type-choice
value-rule = primitive-rule / array-rule / object-rule
member-rule = annotations
member-name-spec *sp-cmt ":" *sp-cmt type-rule
member-name-spec = regex / q-string
type-rule = value-rule / type-choice / target-rule-name
type-choice = annotations "(" type-choice-items
*( choice-combiner type-choice-items ) ")"
explicit-type-choice = type-designator type-choice
type-choice-items = *sp-cmt ( type-choice / type-rule ) *sp-cmt
annotations = *( "@{" *sp-cmt annotation-set *sp-cmt "}" rule-name = name
*sp-cmt ) target-rule-name = annotations "$"
[ ruleset-id-alias "." ]
rule-name
name = ALPHA *( ALPHA / DIGIT / "-" / "-" )
annotation-set = not-annotation / unordered-annotation / rule-def = member-rule / type-designator rule-def-type-rule /
root-annotation / tbd-annotation array-rule / object-rule / group-rule /
not-annotation = not-kw target-rule-name
unordered-annotation = unordered-kw type-designator = type-kw 1*sp-cmt / ":" *sp-cmt
root-annotation = root-kw rule-def-type-rule = value-rule / type-choice
tbd-annotation = annotation-name [ spaces annotation-parameters ] value-rule = primitive-rule / array-rule / object-rule
annotation-name = name member-rule = annotations
annotation-parameters = multi-line-parameters member-name-spec *sp-cmt ":" *sp-cmt type-rule
member-name-spec = regex / q-string
type-rule = value-rule / type-choice / target-rule-name
type-choice = annotations "(" type-choice-items
*( choice-combiner type-choice-items ) ")"
explicit-type-choice = type-designator type-choice
type-choice-items = *sp-cmt ( type-choice / type-rule ) *sp-cmt
primitive-rule = annotations primitive-def annotations = *( "@{" *sp-cmt annotation-set *sp-cmt "}"
primitive-def = string-type / string-range / string-value / *sp-cmt )
null-type / boolean-type / true-value / annotation-set = not-annotation / unordered-annotation /
false-value / double-type / float-type / root-annotation / tbd-annotation
float-range / float-value / not-annotation = not-kw
integer-type / integer-range / integer-value / unordered-annotation = unordered-kw
sized-int-type / sized-uint-type / ipv4-type / root-annotation = root-kw
ipv6-type / ipaddr-type / fqdn-type / idn-type / tbd-annotation = annotation-name [ spaces annotation-parameters ]
uri-type / phone-type / email-type / annotation-name = name
datetime-type / date-type / time-type / annotation-parameters = multi-line-parameters
hex-type / base32hex-type / base32-type /
base64url-type / base64-type / any
null-type = null-kw
boolean-type = boolean-kw
true-value = true-kw
false-value = false-kw
string-type = string-kw
string-value = q-string
string-range = regex
double-type = double-kw
float-type = float-kw
float-range = float-min ".." [ float-max ] / ".." float-max
float-min = float
float-max = float
float-value = float
integer-type = integer-kw
integer-range = integer-min ".." [ integer-max ] /
".." integer-max
integer-min = integer
integer-max = integer
integer-value = integer
sized-int-type = int-kw pos-integer
sized-uint-type = uint-kw pos-integer
ipv4-type = ipv4-kw
ipv6-type = ipv6-kw
ipaddr-type = ipaddr-kw
fqdn-type = fqdn-kw
idn-type = idn-kw
uri-type = uri-kw [ ".." uri-scheme ]
phone-type = phone-kw
email-type = email-kw
datetime-type = datetime-kw
date-type = date-kw
time-type = time-kw
hex-type = hex-kw
base32hex-type = base32hex-kw
base32-type = base32-kw
base64url-type = base64url-kw
base64-type = base64-kw
any = any-kw
object-rule = annotations "{" *sp-cmt primitive-rule = annotations primitive-def
[ object-items *sp-cmt ] "}" primitive-def = string-type / string-range / string-value /
object-items = object-item (*( sequence-combiner object-item ) / null-type / boolean-type / true-value /
*( choice-combiner object-item ) ) false-value / double-type / float-type /
object-item = object-item-types *sp-cmt [ repetition ] float-range / float-value /
object-item-types = object-group / member-rule / target-rule-name integer-type / integer-range / integer-value /
object-group = "(" *sp-cmt [ object-items *sp-cmt ] ")" sized-int-type / sized-uint-type / ipv4-type /
ipv6-type / ipaddr-type / fqdn-type / idn-type /
uri-type / phone-type / email-type /
datetime-type / date-type / time-type /
hex-type / base32hex-type / base32-type /
base64url-type / base64-type / any
null-type = null-kw
boolean-type = boolean-kw
true-value = true-kw
false-value = false-kw
string-type = string-kw
string-value = q-string
string-range = regex
double-type = double-kw
float-type = float-kw
float-range = float-min ".." [ float-max ] / ".." float-max
float-min = float
float-max = float
float-value = float
integer-type = integer-kw
integer-range = integer-min ".." [ integer-max ] /
".." integer-max
integer-min = integer
integer-max = integer
integer-value = integer
sized-int-type = int-kw pos-integer
sized-uint-type = uint-kw pos-integer
ipv4-type = ipv4-kw
ipv6-type = ipv6-kw
ipaddr-type = ipaddr-kw
fqdn-type = fqdn-kw
idn-type = idn-kw
uri-type = uri-kw [ ".." uri-scheme ]
phone-type = phone-kw
email-type = email-kw
datetime-type = datetime-kw
date-type = date-kw
time-type = time-kw
hex-type = hex-kw
base32hex-type = base32hex-kw
base32-type = base32-kw
base64url-type = base64url-kw
base64-type = base64-kw
any = any-kw
array-rule = annotations "[" *sp-cmt [ array-items *sp-cmt ] "]" object-rule = annotations "{" *sp-cmt
array-items = array-item (*( sequence-combiner array-item ) / [ object-items *sp-cmt ] "}"
*( choice-combiner array-item ) ) object-items = object-item [ 1*( sequence-combiner object-item ) /
array-item = array-item-types *sp-cmt [ repetition ] 1*( choice-combiner object-item ) ]
array-item-types = array-group / type-rule / explicit-type-choice object-item = object-item-types *sp-cmt [ repetition *sp-cmt ]
array-group = "(" *sp-cmt [ array-items *sp-cmt ] ")" object-item-types = object-group / member-rule / target-rule-name
object-group = annotations "(" *sp-cmt [ object-items *sp-cmt ] ")"
group-rule = annotations "(" *sp-cmt [ group-items *sp-cmt ] ")" array-rule = annotations "[" *sp-cmt [ array-items *sp-cmt ] "]"
group-items = group-item (*( sequence-combiner group-item ) / array-items = array-item [ 1*( sequence-combiner array-item ) /
*( choice-combiner group-item ) ) 1*( choice-combiner array-item ) ]
group-item = group-item-types *sp-cmt [ repetition ] array-item = array-item-types *sp-cmt [ repetition *sp-cmt ]
group-item-types = group-group / member-rule / array-item-types = array-group / type-rule / explicit-type-choice
type-rule / explicit-type-choice array-group = annotations "(" *sp-cmt [ array-items *sp-cmt ] ")"
group-group = group-rule
sequence-combiner = *sp-cmt "," *sp-cmt group-rule = annotations "(" *sp-cmt [ group-items *sp-cmt ] ")"
choice-combiner = *sp-cmt "|" *sp-cmt group-items = group-item [ 1*( sequence-combiner group-item ) /
1*( choice-combiner group-item ) ]
group-item = group-item-types *sp-cmt [ repetition *sp-cmt ]
group-item-types = group-group / member-rule /
type-rule / explicit-type-choice
group-group = group-rule
sequence-combiner = "," *sp-cmt
choice-combiner = "|" *sp-cmt
repetition = optional / one-or-more / repetition = optional / one-or-more /
repetition-range / zero-or-more repetition-range / zero-or-more
optional = "?" optional = "?"
one-or-more = "+" [ repetition-step ] one-or-more = "+" [ repetition-step ]
zero-or-more = "*" [ repetition-step ] zero-or-more = "*" [ repetition-step ]
repetition-range = "*" *sp-cmt ( repetition-range = "*" *sp-cmt (
min-max-repetition / min-repetition / min-max-repetition / min-repetition /
max-repetition / specific-repetition ) max-repetition / specific-repetition )
min-max-repetition = min-repeat ".." max-repeat min-max-repetition = min-repeat ".." max-repeat
[ repetition-step ] [ repetition-step ]
min-repetition = min-repeat ".." [ repetition-step ]
max-repetition = ".." max-repeat [ repetition-step ]
min-repeat = non-neg-integer
max-repeat = non-neg-integer
specific-repetition = non-neg-integer
repetition-step = "%" step-size
step-size = non-neg-integer
min-repetition = min-repeat ".." [ repetition-step ] integer = "0" / ["-"] pos-integer
max-repetition = ".." max-repeat [ repetition-step ] non-neg-integer = "0" / pos-integer
min-repeat = non-neg-integer pos-integer = digit1-9 *DIGIT
max-repeat = non-neg-integer
specific-repetition = non-neg-integer
repetition-step = "%" step-size
step-size = non-neg-integer
integer = "0" / ["-"] pos-integer float = [ minus ] int frac [ exp ]
non-neg-integer = "0" / pos-integer ; From RFC 7159 except 'frac' required
pos-integer = digit1-9 *DIGIT minus = %x2D ; -
plus = %x2B ; +
int = zero / ( digit1-9 *DIGIT )
digit1-9 = %x31-39 ; 1-9
frac = decimal-point 1*DIGIT
decimal-point = %x2E ; .
exp = e [ minus / plus ] 1*DIGIT
e = %x65 / %x45 ; e E
zero = %x30 ; 0
float = [ minus ] int frac [ exp ] q-string = quotation-mark *char quotation-mark
; From RFC 7159 except 'frac' required ; From RFC 7159
minus = %x2D ; - char = unescaped /
plus = %x2B ; + escape (
int = zero / ( digit1-9 *DIGIT ) %x22 / ; " quotation mark U+0022
digit1-9 = %x31-39 ; 1-9 %x5C / ; \ reverse solidus U+005C
frac = decimal-point 1*DIGIT %x2F / ; / solidus U+002F
decimal-point = %x2E ; . %x62 / ; b backspace U+0008
exp = e [ minus / plus ] 1*DIGIT %x66 / ; f form feed U+000C
e = %x65 / %x45 ; e E %x6E / ; n line feed U+000A
zero = %x30 ; 0 %x72 / ; r carriage return U+000D
%x74 / ; t tab U+0009
%x75 4HEXDIG ) ; uXXXX U+XXXX
escape = %x5C ; \
quotation-mark = %x22 ; "
unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
q-string = quotation-mark *char quotation-mark regex = "/" *( escape "/" / not-slash ) "/"
; From RFC 7159 [ regex-modifiers ]
char = unescaped / not-slash = HTAB / CR / LF / %x20-2E / %x30-10FFFF
escape ( ; Any char except "/"
%x22 / ; " quotation mark U+0022 regex-modifiers = *( "i" / "s" / "x" )
%x5C / ; \ reverse solidus U+005C
%x2F / ; / solidus U+002F
%x62 / ; b backspace U+0008
%x66 / ; f form feed U+000C
%x6E / ; n line feed U+000A
%x72 / ; r carriage return U+000D
%x74 / ; t tab U+0009
%x75 4HEXDIG ) ; uXXXX U+XXXX
escape = %x5C ; \
quotation-mark = %x22 ; "
unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
regex = "/" *( escape "/" / not-slash ) "/" uri-scheme = 1*ALPHA
[ regex-modifiers ]
not-slash = HTAB / CR / LF / %x20-2E / %x30-10FFFF
; Any char except "/"
regex-modifiers = *( "i" / "s" / "x" )
uri-scheme = 1*ALPHA ;; Keywords
;; Keywords any-kw = %x61.6E.79 ; "any"
any-kw = %x61.6E.79 ; "any" as-kw = %x61.73 ; "as"
as-kw = %x61.73 ; "as" base32-kw = %x62.61.73.65.33.32 ; "base32"
base32-kw = %x62.61.73.65.33.32 ; "base32" base32hex-kw = %x62.61.73.65.33.32.68.65.78 ; "base32hex"
base32hex-kw = %x62.61.73.65.33.32.68.65.78 ; "base32hex" base64-kw = %x62.61.73.65.36.34 ; "base64"
base64-kw = %x62.61.73.65.36.34 ; "base64" base64url-kw = %x62.61.73.65.36.34.75.72.6C ; "base64url"
base64url-kw = %x62.61.73.65.36.34.75.72.6C ; "base64url" boolean-kw = %x62.6F.6F.6C.65.61.6E ; "boolean"
boolean-kw = %x62.6F.6F.6C.65.61.6E ; "boolean" date-kw = %x64.61.74.65 ; "date"
date-kw = %x64.61.74.65 ; "date" datetime-kw = %x64.61.74.65.74.69.6D.65 ; "datetime"
datetime-kw = %x64.61.74.65.74.69.6D.65 ; "datetime" double-kw = %x64.6F.75.62.6C.65 ; "double"
double-kw = %x64.6F.75.62.6C.65 ; "double" email-kw = %x65.6D.61.69.6C ; "email"
email-kw = %x65.6D.61.69.6C ; "email" false-kw = %x66.61.6C.73.65 ; "false"
false-kw = %x66.61.6C.73.65 ; "false" float-kw = %x66.6C.6F.61.74 ; "float"
float-kw = %x66.6C.6F.61.74 ; "float" fqdn-kw = %x66.71.64.6E ; "fqdn"
fqdn-kw = %x66.71.64.6E ; "fqdn" hex-kw = %x68.65.78 ; "hex"
hex-kw = %x68.65.78 ; "hex" idn-kw = %x69.64.6E ; "idn"
idn-kw = %x69.64.6E ; "idn" import-kw = %x69.6D.70.6F.72.74 ; "import"
import-kw = %x69.6D.70.6F.72.74 ; "import" int-kw = %x69.6E.74 ; "int"
int-kw = %x69.6E.74 ; "int" integer-kw = %x69.6E.74.65.67.65.72 ; "integer"
integer-kw = %x69.6E.74.65.67.65.72 ; "integer" ipaddr-kw = %x69.70.61.64.64.72 ; "ipaddr"
ipaddr-kw = %x69.70.61.64.64.72 ; "ipaddr" ipv4-kw = %x69.70.76.34 ; "ipv4"
ipv4-kw = %x69.70.76.34 ; "ipv4" ipv6-kw = %x69.70.76.36 ; "ipv6"
ipv6-kw = %x69.70.76.36 ; "ipv6" jcr-version-kw = %x6A.63.72.2D.76.65.72.73.69.6F.6E ; "jcr-version"
jcr-version-kw = %x6A.63.72.2D.76.65.72.73.69.6F.6E ; "jcr-version" not-kw = %x6E.6F.74 ; "not"
not-kw = %x6E.6F.74 ; "not" null-kw = %x6E.75.6C.6C ; "null"
null-kw = %x6E.75.6C.6C ; "null" phone-kw = %x70.68.6F.6E.65 ; "phone"
phone-kw = %x70.68.6F.6E.65 ; "phone" root-kw = %x72.6F.6F.74 ; "root"
root-kw = %x72.6F.6F.74 ; "root" ruleset-id-kw = %x72.75.6C.65.73.65.74.2D.69.64 ; "ruleset-id"
ruleset-id-kw = %x72.75.6C.65.73.65.74.2D.69.64 ; "ruleset-id" string-kw = %x73.74.72.69.6E.67 ; "string"
string-kw = %x73.74.72.69.6E.67 ; "string" time-kw = %x74.69.6D.65 ; "time"
time-kw = %x74.69.6D.65 ; "time" true-kw = %x74.72.75.65 ; "true"
true-kw = %x74.72.75.65 ; "true" type-kw = %x74.79.70.65 ; "type"
type-kw = %x74.79.70.65 ; "type" uint-kw = %x75.69.6E.74 ; "uint"
uint-kw = %x75.69.6E.74 ; "uint" unordered-kw = %x75.6E.6F.72.64.65.72.65.64 ; "unordered"
unordered-kw = %x75.6E.6F.72.64.65.72.65.64 ; "unordered" uri-kw = %x75.72.69 ; "uri"
uri-kw = %x75.72.69 ; "uri"
;; Referenced RFC 5234 Core Rules ;; Referenced RFC 5234 Core Rules
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
CR = %x0D ; carriage return CR = %x0D ; carriage return
DIGIT = %x30-39 ; 0-9 DIGIT = %x30-39 ; 0-9
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
HTAB = %x09 ; horizontal tab HTAB = %x09 ; horizontal tab
LF = %x0A ; linefeed LF = %x0A ; linefeed
SP = %x20 ; space SP = %x20 ; space
WSP = SP / HTAB ; white space WSP = SP / HTAB ; white space
Figure 70: ABNF for JSON Content Rules Figure 70: ABNF for JSON Content Rules
8. Acknowledgements 9. Acknowledgements
John Cowan, Andrew Biggs, Paul Kyzivat and Paul Jones provided John Cowan, Andrew Biggs, Paul Kyzivat and Paul Jones provided
feedback and suggestions which led to many changes in the syntax. feedback and suggestions which led to many changes in the syntax.
9. References 10. References
9.1. Normative References 10.1. Normative References
[JCR_ABNF]
Newton, A. and P. Cordell, "ABNF for JSON Content Rules",
<https://raw.githubusercontent.com/arineng/jcr/master/
jcr-abnf.txt>.
[RFC1166] Kirkpatrick, S., Stahl, M., and M. Recker, "Internet [RFC1166] Kirkpatrick, S., Stahl, M., and M. Recker, "Internet
numbers", RFC 1166, July 1990. numbers", RFC 1166, DOI 10.17487/RFC1166, July 1990,
<https://www.rfc-editor.org/info/rfc1166>.
[RFC3339] Klyne, G., Ed. and C. Newman, "Date and Time on the [RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet:
Internet: Timestamps", RFC 3339, July 2002. Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002,
<https://www.rfc-editor.org/info/rfc3339>.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66, RFC Resource Identifier (URI): Generic Syntax", STD 66,
3986, January 2005. RFC 3986, DOI 10.17487/RFC3986, January 2005,
<https://www.rfc-editor.org/info/rfc3986>.
[RFC4234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax [RFC4234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", RFC 4234, October 2005. Specifications: ABNF", RFC 4234, DOI 10.17487/RFC4234,
October 2005, <https://www.rfc-editor.org/info/rfc4234>.
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
Encodings", RFC 4648, October 2006. Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
<https://www.rfc-editor.org/info/rfc4648>.
[RFC5322] Resnick, P., Ed., "Internet Message Format", RFC 5322, [RFC5322] Resnick, P., Ed., "Internet Message Format", RFC 5322,
October 2008. DOI 10.17487/RFC5322, October 2008,
<https://www.rfc-editor.org/info/rfc5322>.
[RFC5952] Kawamura, S. and M. Kawashima, "A Recommendation for IPv6 [RFC5952] Kawamura, S. and M. Kawashima, "A Recommendation for IPv6
Address Text Representation", RFC 5952, August 2010. Address Text Representation", RFC 5952,
DOI 10.17487/RFC5952, August 2010,
[RFC7159] Bray, T., "The JavaScript Object Notation (JSON) Data <https://www.rfc-editor.org/info/rfc5952>.
Interchange Format", RFC 7159, March 2014.
[JCR_ABNF] [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Newton, A. and P. Cordell, "ABNF for JSON Content Rules", Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March
<https://raw.githubusercontent.com/arineng/jcr/08/jcr- 2014, <https://www.rfc-editor.org/info/rfc7159>.
abnf.txt>.
9.2. Infomative References 10.2. Infomative References
[I-D.cordell-jcr-co-constraints] [I-D.cordell-jcr-co-constraints]
Cordell, P. and A. Newton, "Co-Constraints for JSON Cordell, P. and A. Newton, "Co-Constraints for JSON
Content Rules", draft-cordell-jcr-co-constraints-00 (work Content Rules", draft-cordell-jcr-co-constraints-00 (work
in progress), March 2016. in progress), March 2016.
[JCR_SPECIFICATION_FIGURES] [RFC7492] Bhatia, M., Zhang, D., and M. Jethanandani, "Analysis of
Newton, A. and P. Cordell, "Figures in the JCR Bidirectional Forwarding Detection (BFD) Security
Specification", <https://github.com/arineng/jcr/tree/08/ According to the Keying and Authentication for Routing
figs>. Protocols (KARP) Design Guidelines", RFC 7492,
DOI 10.17487/RFC7492, March 2015,
<https://www.rfc-editor.org/info/rfc7492>.
[ARIN_JCR_VALIDATOR] 10.3. URIs
American Registry for Internet Numbers, "JSON Content
Rules Validator (Work In Progress)",
<https://github.com/arineng/jcrvalidator>.
[CODALOGIC_JCR_VALIDATOR] [1] https://github.com/arineng/jcr/tree/master/figs
Codalogic, "cl-jcr-parser (Work In Progress)",
<https://github.com/codalogic/cl-jcr-parser>.
Appendix A. Co-Constraints Appendix A. Co-Constraints
This specification defines a small set of annotations and directives This specification defines a small set of annotations and directives
for JCR, yet the syntax is extensible allowing for other annotations for JCR, yet the syntax is extensible allowing for other annotations
and directives. [I-D.cordell-jcr-co-constraints] ("Co-Constraints and directives. [I-D.cordell-jcr-co-constraints] ("Co-Constraints
for JCR") defines further annotations and directives which define for JCR") defines further annotations and directives which define
more detailed constraints on JSON messages, including co-constraints more detailed constraints on JSON messages, including co-constraints
(constraining parts of JSON message based on another part of a JSON (constraining parts of JSON message based on another part of a JSON
message). message).
skipping to change at page 40, line 47 skipping to change at page 42, line 22
complex than that which can be expressed in JCR, sometimes involving complex than that which can be expressed in JCR, sometimes involving
variables and interdependencies which can only be expressed in a variables and interdependencies which can only be expressed in a
programming language. programming language.
A JCR processor may provide a mechanism for the execution of local A JCR processor may provide a mechanism for the execution of local
functions or methods based on the name of a rule being evaluated. functions or methods based on the name of a rule being evaluated.
Such a mechanism could pass to the function the data to be evaluated, Such a mechanism could pass to the function the data to be evaluated,
and that function could return to the processor the result of and that function could return to the processor the result of
evaluating the data in the function. evaluating the data in the function.
Appendix C. JCR Implementations Appendix C. Changes from -07 and -08
The following implementations, [ARIN_JCR_VALIDATOR] and
[CODALOGIC_JCR_VALIDATOR] have influenced the development of this
document.
Appendix D. Syntax Changes from -06 and -07
The differences between this document and -07 are not significant, as
this version of this draft is provided for the purposes of keeping
the document active within the IETF archives.
The syntax described in this document is changed significantly, and
in a non-backwards compatible manner, from the syntax described in
the -06 version of this specification. The vast majority of these
changes have occurred to meet the goals of the syntax being a
superset of JSON and easy to comprehend by a casual reader unfamiliar
with JCR but familiar with JSON.
The latter of those two goals is subjective, and therefore a series
of focus group sessions were convened where participants, all
professional software developers with familiarity with JSON but not
JCR, were asked to read and interpret various rulesets and allowed to
offer suggested improvements. Outcomes of these sessions resulted in
many changes, such as the use of '$' characters to note rule names
and the change of the repetition syntax.
Other changes came from feedback given directly to the authors via
email and on the IETF JSON Working Group mailing list.
Most figures from this document can be found in file form at This revision of the document makes no substantive changes to any
[JCR_SPECIFICATION_FIGURES]. parts of the specification. Some of the ABNF has been updated to
more correctly allow group rules, and other small change have been
made to the ABNF to make it simpler.
Authors' Addresses Authors' Addresses
Andrew Lee Newton Andrew Lee Newton
American Registry for Internet Numbers American Registry for Internet Numbers
PO Box 232290 PO Box 232290
Centreville, VA 20120 Centreville, VA 20120
US US
Email: andy@arin.net Email: andy@arin.net
 End of changes. 45 change blocks. 
329 lines changed or deleted 375 lines changed or added

This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/