diff --git a/spec/latest/json-ld-api/index.html b/spec/latest/json-ld-api/index.html index adf1e2c89..7914d3acc 100644 --- a/spec/latest/json-ld-api/index.html +++ b/spec/latest/json-ld-api/index.html @@ -1067,11 +1067,18 @@

Algorithm

@container key, which must be either @list, @set, @index, @id, @type - or @language. Otherwise, an + or @language, + + or an array containing exactly any one of those keywords, + or a combination of @set and any of @index, + @id, @type, @language + in any order + . + Otherwise, an invalid container mapping has been detected and processing is aborted.
  • If processingMode is json-ld-1.0 and the container value - is @id or @type, an + is @id or @type, or is otherwise not a string, an invalid container mapping has been detected and processing is aborted.
  • Set the container mapping of definition to @@ -1961,9 +1968,13 @@

    Algorithm

  • If result contains only one item (it has a length of - 1), active property has no - container mapping in active context, and - compactArrays + 1), + + active property is not @graph or @set, + or the container mapping for active property in + active context does not include @list or @set, + + and compactArrays is true, set result to its only item.
  • Return result.
  • @@ -2161,7 +2172,13 @@

    Algorithm

  • Initialize container to null. If there is a container mapping for item active property in active context, - set container to its value.
  • + set container to the first + such value other than @set. +
  • Initialize as array to + true or false depending on if the container mapping for + item active property in active context + includes @set or if item active property + is @graph or @list.
  • Initialize compacted item to the result of using this algorithm recursively, passing active context, inverse context, @@ -2204,7 +2221,7 @@

    Algorithm

  • - If container is @language, + If container includes @language, @index, @id, or @type:
      @@ -2242,6 +2259,9 @@

      Algorithm

      compacted container in compacted value to those remaining values. Otherwise, remove that key-value pair from compacted item. +
    1. If compacted item is not an + array and as array is true, + set compacted item to an array containing that value.
    2. If map key is not a key in map object, then set this key's value in map object to compacted item. Otherwise, if the value @@ -2255,9 +2275,7 @@

      Algorithm

      1. If compactArrays - is false, container is @set or - @list, or expanded property is - @list or @graph and + is false, as array is true and compacted item is not an array, set it to a new array containing only compacted item.
      2. @@ -2362,10 +2380,14 @@

        Algorithm

      3. If the term definition is null, term cannot be selected during compaction, so continue to the next term.
      4. -
      5. Initialize container to @none. If there - is a container mapping in - term definition, set container to - its associated value.
      6. +
      7. Initialize container to @none. If + + the container mapping in term definition + includes @id, @index, + @language, @list, @type, or + @set in that order + set container to + the first such value found.
      8. Initialize iri to the value of the IRI mapping for the term definition.
      9. If iri is not a key in result, add @@ -4507,6 +4529,11 @@

        Changes since 1.0 Recommendation of 16 January 2014

      10. The JSON syntax has been abstracted into an internal representation to allow for other seriazation formats that are functionally equivalent to JSON.
      11. +
      12. The value for @container in an expanded term definition + can also be an array containing any appropriate container + keyword along with @set (other than @list). + This allows a way to ensure that such property values will always + be expressed in array form.
      13. diff --git a/spec/latest/json-ld/index.html b/spec/latest/json-ld/index.html index fa0efc860..ed77cf911 100644 --- a/spec/latest/json-ld/index.html +++ b/spec/latest/json-ld/index.html @@ -374,7 +374,12 @@

        Syntax Tokens and Keywords

        .
        @container
        Used to set the default container type for a term. - This keyword is described in .
        + This keyword is described in , + , + , + , and + + .
        @list
        Used to express an ordered set of data. This keyword is described in .
        @@ -2590,6 +2595,108 @@

        Data Indexing

        + +

        The value of @container can also + be an array containing both @index and @set. + When compacting, this ensures that a JSON-LD Processor will use + the array form for all values of indexes.

        + +
        +  
        +  
        + + +
        +

        Language Indexing

        + +

        JSON which includes string values in multiple languages may be + represented using a language map to allow for easily + indexing property values by language tag. This enables direct access to + lanugage values instead of having to scan an array in search of a specific item. + In JSON-LD such data can be specified by associating the + @language keyword with a + @container declaration in the context:

        + +
        +  
        +  
        + +

        In the example above, the label term has + been marked as an language map. The en and + de keys are implicitly associated with their respective + values by the JSON-LD Processor. This allows a developer to + access the German version of the label using the + following code snippet: obj.label.de.

        + +

        The value of @container can also + be an array containing both @language and @set. + When compacting, this ensures that a JSON-LD Processor will use + the array form for all values of language tags.

        + +
        +  
        +  
        @@ -2644,6 +2751,42 @@

        Node Identifier Indexing

        as that in using a JSON-LD processor.

        +

        The value of @container can also + be an array containing both @id and @set. + When compacting, this ensures that a JSON-LD Processor will use + the array form for all values of node identifiers.

        + +
        +  
        +  
        +

        Id maps are a new feature in JSON-LD 1.1, requiring processing mode set to json-ld-1.1

        @@ -2661,7 +2804,7 @@

        Node Type Indexing

        @container declaration in the context:

        +       title="Indexing data in JSON-LD by type">
           
        @@ -2693,6 +2835,39 @@ 

        Node Type Indexing

        schema:ProfessionalService keys will be interpreted as the @type property of the node object value.

        +

        The value of @container can also + be an array containing both @type and @set. + When compacting, this ensures that a JSON-LD Processor will use + the array form for all values of types.

        + +
        +  
        +  
        +

        Type maps are a new feature in JSON-LD 1.1, requiring processing mode set to json-ld-1.1

        @@ -2784,7 +2959,7 @@

        Expanded Document Form

        The JSON-LD Processing Algorithms and API specification [[JSON-LD-API]] defines a method for expanding a JSON-LD document. - Expansion is the process of taking a JSON-LD document and applying a + Expansion is the process of taking a JSON-LD document and applying a @context such that all IRIs, types, and values are expanded so that the @context is no longer necessary.

        @@ -2807,7 +2982,7 @@

        Expanded Document Form

        -->
        -

        Running the JSON-LD Expansion algorithm against the JSON-LD input document +

        Running the JSON-LD Expansion algorithm against the JSON-LD input document provided above would result in the following output:

        Expanded Document Form
           

        Compacted Document Form

        The JSON-LD Processing Algorithms and API specification [[JSON-LD-API]] defines - a method for compacting a JSON-LD document. Compaction is the process + a method for compacting a JSON-LD document. Compaction is the process of applying a developer-supplied context to shorten IRIs to terms or compact IRIs and JSON-LD values expressed in expanded form to simple values such as @@ -2880,7 +3055,7 @@

        Compacted Document Form

        -->
        -

        Running the JSON-LD Compaction algorithm given the context supplied above +

        Running the JSON-LD Compaction algorithm given the context supplied above against the JSON-LD input document provided above would result in the following output:

        @@ -2911,7 +3086,7 @@

        Compacted Document Form

        Flattened Document Form

        The JSON-LD Processing Algorithms and API specification [[JSON-LD-API]] defines - a method for flattening a JSON-LD document. Flattening collects all + a method for flattening a JSON-LD document. Flattening collects all properties of a node in a single JSON object and labels all blank nodes with blank node identifiers. @@ -2942,7 +3117,7 @@

        Flattened Document Form

        --> -

        Running the JSON-LD Flattening algorithm against the JSON-LD input document in +

        Running the JSON-LD Flattening algorithm against the JSON-LD input document in the example above and using the same context would result in the following output:

        @@ -3367,14 +3542,17 @@

        Language Maps

        A language map is used to associate a language with a value in a way that allows easy programmatic access. A language map may be used as a term value within a node object if the term is defined - with @container set to @language. The keys of a + with @container set to @language, + + or an array containing both @language and @set + . The keys of a language map MUST be strings representing [[BCP47]] language codes and the values MUST be any of the following types:

        See for further discussion @@ -3388,7 +3566,10 @@

        Index Maps

        but should be preserved regardless, to be used in JSON-LD documents. An index map may be used as a term value within a node object if the - term is defined with @container set to @index. + term is defined with @container set to @index, + + or an array containing both @index and @set + . The values of the members of an index map MUST be one of the following types:

        @@ -3413,7 +3594,9 @@

        Id Maps

        An id map is used to associate an IRI with a value that allows easy programatic access. An id map may be used as a term value within a node object if the term - is defined with @container set to @id. The keys of an id map MUST be IRIs + is defined with @container set to @id, + or an array containing both @id and @set. + The keys of an id map MUST be IRIs (relative IRI, compact IRI (including blank node identifiers), or absolute IRI) and the values MUST be node objects.

        @@ -3427,7 +3610,9 @@

        Type Maps

        A type map is used to associate an IRI with a value that allows easy programatic access. A type map may be used as a term value within a node object if the term - is defined with @container set to @type. The keys of a type map MUST be IRIs + is defined with @container set to @type, + or an array containing both @type and @set. + The keys of a type map MUST be IRIs (relative IRI, compact IRI (including blank node identifiers), or absolute IRI) and the values MUST be node objects.

        @@ -3443,7 +3628,7 @@

        Property Nesting

        A nested property is used to gather properties of a node object in a separate JSON object, or array of JSON objects which are not value objects. It is semantically transparent and is removed - during the process of expansion. Property nesting is recursive, and + during the process of expansion. Property nesting is recursive, and collections of nested properties may contain further nesting.

        Semantically, nesting is treated as if the properties and values were declared directly @@ -3516,7 +3701,14 @@

        Context Definitions

        If the expanded term definition contains the @container keyword, its value MUST be either @list, @set, - @language, @index, @id, @type or be null. If the value + @language, @index, @id, @type or be null + + or an array containing exactly any one of those keywords, + or a combination of @set and any of @index, + @id, @type, @language + in any order + . + If the value is @language, when the term is used outside of the @context, the associated value MUST be a language map. If the value is @index, when the term is used outside of @@ -3631,7 +3823,7 @@

        Serializing/Deserializing RDF

        1. Expand the JSON-LD document, removing any context; this ensures that properties, types, and values are given their full representation - as IRIs and expanded values. Expansion + as IRIs and expanded values. Expansion is discussed further in .
        2. Flatten the document, which turns the document into an array of node objects. Flattening is discussed @@ -3663,7 +3855,7 @@

          Serializing/Deserializing RDF

          --> -

          Running the JSON-LD Expansion and Flattening algorithms against the +

          Running the JSON-LD Expansion and Flattening algorithms against the JSON-LD input document in the example above would result in the following output:

          @@ -3730,6 +3922,12 @@

          Changes since 1.0 Recommendation of 16 January 2014

        3. The JSON syntax has been abstracted into an internal representation to allow for other serializations that are functionally equivalent to JSON.
        4. +
        5. Added .
        6. +
        7. The value for @container in an expanded term definition + can also be an array containing any appropriate container + keyword along with @set (other than @list). + This allows a way to ensure that such property values will always + be expressed in array form.
        8. diff --git a/test-suite/tests/compact-manifest.jsonld b/test-suite/tests/compact-manifest.jsonld index 31cadb640..1cf5c3953 100644 --- a/test-suite/tests/compact-manifest.jsonld +++ b/test-suite/tests/compact-manifest.jsonld @@ -836,6 +836,24 @@ "context": "compact-n010-context.jsonld", "expect": "compact-n010-out.jsonld", "option": {"processingMode": "json-ld-1.1"} + }, { + "@id": "#ts001", + "@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"], + "name": "@context with single array values", + "purpose": "@context values may be in an array", + "input": "compact-s001-in.jsonld", + "context": "compact-s001-context.jsonld", + "expect": "compact-s001-out.jsonld", + "option": {"processingMode": "json-ld-1.1"} + }, { + "@id": "#ts001", + "@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"], + "name": "@context with array including @set uses array values", + "purpose": "@context values may include @set along with another compatible value", + "input": "compact-s002-in.jsonld", + "context": "compact-s002-context.jsonld", + "expect": "compact-s002-out.jsonld", + "option": {"processingMode": "json-ld-1.1"} } ] } diff --git a/test-suite/tests/compact-s001-context.jsonld b/test-suite/tests/compact-s001-context.jsonld new file mode 100644 index 000000000..41a0cf97d --- /dev/null +++ b/test-suite/tests/compact-s001-context.jsonld @@ -0,0 +1,10 @@ +{ + "@context": { + "mylist": {"@id": "http://example.com/mylist", "@container": ["@list"]}, + "myset": {"@id": "http://example.com/myset", "@container": ["@set"]}, + "myid": {"@id": "http://example.com/myid", "@container": ["@id"]}, + "mytype": {"@id": "http://example.com/mytype", "@container": ["@type"]}, + "mylanguage": {"@id": "http://example.com/mylanguage", "@container": ["@language"]}, + "myindex": {"@id": "http://example.com/myindex", "@container": ["@index"]} + } +} \ No newline at end of file diff --git a/test-suite/tests/compact-s001-in.jsonld b/test-suite/tests/compact-s001-in.jsonld new file mode 100644 index 000000000..459a2978a --- /dev/null +++ b/test-suite/tests/compact-s001-in.jsonld @@ -0,0 +1,9 @@ +{ + "@id": "http://example.org/id", + "http://example.com/mylist": {"@list": ["foo"]}, + "http://example.com/myset": "foo", + "http://example.com/myid": {"@id": "http://example/id", "@type": "http://example/type"}, + "http://example.com/mytype": {"@id": "http://example/id", "@type": "http://example/type"}, + "http://example.com/mylanguage": {"@value": "foo", "@language": "en"}, + "http://example.com/myindex": {"@value": "foo", "@index": "bar"} +} \ No newline at end of file diff --git a/test-suite/tests/compact-s001-out.jsonld b/test-suite/tests/compact-s001-out.jsonld new file mode 100644 index 000000000..07b414597 --- /dev/null +++ b/test-suite/tests/compact-s001-out.jsonld @@ -0,0 +1,17 @@ +{ + "@context": { + "mylist": {"@id": "http://example.com/mylist", "@container": ["@list"]}, + "myset": {"@id": "http://example.com/myset", "@container": ["@set"]}, + "myid": {"@id": "http://example.com/myid", "@container": ["@id"]}, + "mytype": {"@id": "http://example.com/mytype", "@container": ["@type"]}, + "mylanguage": {"@id": "http://example.com/mylanguage", "@container": ["@language"]}, + "myindex": {"@id": "http://example.com/myindex", "@container": ["@index"]} + }, + "@id": "http://example.org/id", + "mylist": ["foo"], + "myset": ["foo"], + "myid": {"http://example/id": {"@type": "http://example/type"}}, + "mytype": {"http://example/type": {"@id": "http://example/id"}}, + "mylanguage": {"en": "foo"}, + "myindex": {"bar": "foo"} +} \ No newline at end of file diff --git a/test-suite/tests/compact-s002-context.jsonld b/test-suite/tests/compact-s002-context.jsonld new file mode 100644 index 000000000..b63af60df --- /dev/null +++ b/test-suite/tests/compact-s002-context.jsonld @@ -0,0 +1,8 @@ +{ + "@context": { + "myid": {"@id": "http://example.com/myid", "@container": ["@id", "@set"]}, + "mytype": {"@id": "http://example.com/mytype", "@container": ["@type", "@set"]}, + "mylanguage": {"@id": "http://example.com/mylanguage", "@container": ["@language", "@set"]}, + "myindex": {"@id": "http://example.com/myindex", "@container": ["@index", "@set"]} + } +} \ No newline at end of file diff --git a/test-suite/tests/compact-s002-in.jsonld b/test-suite/tests/compact-s002-in.jsonld new file mode 100644 index 000000000..6b1e951ee --- /dev/null +++ b/test-suite/tests/compact-s002-in.jsonld @@ -0,0 +1,7 @@ +{ + "@id": "http://example.org/id", + "http://example.com/myid": {"@id": "http://example/id", "@type": "http://example/type"}, + "http://example.com/mytype": {"@id": "http://example/id", "@type": "http://example/type"}, + "http://example.com/mylanguage": {"@value": "foo", "@language": "en"}, + "http://example.com/myindex": {"@value": "foo", "@index": "bar"} +} \ No newline at end of file diff --git a/test-suite/tests/compact-s002-out.jsonld b/test-suite/tests/compact-s002-out.jsonld new file mode 100644 index 000000000..aeef6d6d4 --- /dev/null +++ b/test-suite/tests/compact-s002-out.jsonld @@ -0,0 +1,13 @@ +{ + "@context": { + "myid": {"@id": "http://example.com/myid", "@container": ["@id", "@set"]}, + "mytype": {"@id": "http://example.com/mytype", "@container": ["@type", "@set"]}, + "mylanguage": {"@id": "http://example.com/mylanguage", "@container": ["@language", "@set"]}, + "myindex": {"@id": "http://example.com/myindex", "@container": ["@index", "@set"]} + }, + "@id": "http://example.org/id", + "myid": {"http://example/id": [{"@type": "http://example/type"}]}, + "mytype": {"http://example/type": [{"@id": "http://example/id"}]}, + "mylanguage": {"en": ["foo"]}, + "myindex": {"bar": ["foo"]} +} \ No newline at end of file diff --git a/test-suite/tests/error-manifest.jsonld b/test-suite/tests/error-manifest.jsonld index 85ba84095..d2d3a4d1d 100644 --- a/test-suite/tests/error-manifest.jsonld +++ b/test-suite/tests/error-manifest.jsonld @@ -429,6 +429,22 @@ "input": "error-p006-in.jsonld", "context": "error-p006-context.jsonld", "expect": "invalid @version value" + }, { + "@id": "#ts001", + "@type": ["jld:NegativeEvaluationTest", "jld:ExpandTest"], + "name": "Using an array value for @context is illegal in JSON-LD 1.0", + "purpose": "Verifies that an exception is raised on expansion when a invalid container mapping is found", + "input": "error-s001-in.jsonld", + "expect": "invalid container mapping", + "option": {"processingMode": "json-ld-1.0"} + }, { + "@id": "#ts002", + "@type": ["jld:NegativeEvaluationTest", "jld:ExpandTest"], + "name": "Mapping @container: [@list, @set] is invalid", + "purpose": "Testing legal combinations of @set with other container values", + "input": "error-s002-in.jsonld", + "expect": "invalid container mapping", + "option": {"processingMode": "json-ld-1.1"} } ] } diff --git a/test-suite/tests/error-s001-in.jsonld b/test-suite/tests/error-s001-in.jsonld new file mode 100644 index 000000000..d014b4833 --- /dev/null +++ b/test-suite/tests/error-s001-in.jsonld @@ -0,0 +1,7 @@ +{ + "@context": { + "term": {"@id": "http://example/term", "@container": ["@set"]} + }, + "@id": "http://example/test#example", + "term": "foo" +} diff --git a/test-suite/tests/error-s002-in.jsonld b/test-suite/tests/error-s002-in.jsonld new file mode 100644 index 000000000..d71e3eb6f --- /dev/null +++ b/test-suite/tests/error-s002-in.jsonld @@ -0,0 +1,7 @@ +{ + "@context": { + "term": {"@id": "http://example/term", "@container": ["@list", "@set"]} + }, + "@id": "http://example/test#example", + "term": "foo" +}