# DS-V7 - Changelog

In the following, the additions and changes of **DS-V7** in contrast to the previously used version of DS (**DS-V5**) are explained.

## 1. Changes

### 1.1. Use the HTTPS version of schema.org

`https` should become the [standard protocol for the schema.org vocabulary](https://schema.org/docs/faq.html#19). With **DS-V7** we want to switch to `https` for schema.org in all our tools. In the specification, all schema.org links and vocabulary terms should use the `https` version if possible. "Hacks" in tools that understand `http` and `https` interchangeably should only be used if there is no other option (e.g. for the verification, users should be allowed to verify their `http` schema.org annotations. An informational error could be added regarding the better `https` namespace).

The schema.org entry in the `@context` changes to:

```json
"@context": {
  ...
  "schema": "https://schema.org/",
  ...
}
```

### 1.2. Change type of DS node

The `@type` for Domain Specifications is given in the DS node, where the following two classes have been used so far:

```json
{
  "@type": [
    "sh:NodeShape",
    "schema:CreativeWork"
  ],
  "sh:targetClass": [
    "schema:Hotel"
  ],
  ...
}
```

With **DS-V7** this is changed to a class defined in the DS vocabulary, which is `ds:DomainSpecification`. In the DS Vocabulary, the class `ds:DomainSpecification` is a subclass of the two previously used classes, this way we keep the semantic information that was provided before (especially that a DS node is a `sh:NodeShape`).

Example for DS node:

```json
{
  "@type": "ds:DomainSpecification",
  "sh:targetClass": [
    "schema:Hotel"
  ],
  ...
}
```

### 1.3. Multilingual metadata

Metadata properties MUST use language tags in **DS-V7**. This allows the use of multiple descriptions for different languages. The default language for metadata depends on the tool used. Metadata terms concerned by these changes:

* DS node
  * `schema:name`
  * `schema:description`
* Property node
  * `rdfs:comment`

Example for DS node:

```json
{
  "@type": "ds:DomainSpecification",
  "schema:name":  [
    {
      "@language": "en",
      "@value": "Example DS"
    }
  ],
  "schema:description": [
    {
      "@language": "en",
      "@value": "Example DS for our application"
    },
    {
      "@language": "de",
      "@value": "Beispiel DS für unsere Anwendung"
    }
  ],
  ...
}
```

### 1.4. DS and Data matching

The purpose of this change is to **split the term used for the target selection, and the corresponding constraint that generates an error** when the target entity does not comply with the expected match (details below). None of the following terms is mandatory, since there are now different ways to specify the link between data and DS.

#### 1.4.1. sh:targetClass

Up to now, we have used `sh:targetClass` (and to some extent also `sh:targetSubjectsOf` for Knowledge Graphs) to define the target entities that match with the given DS. At the same time, this term has been used as a constraint, restricting the class of the target entity and generating an error if the class of the target entity did not match. In order to be more compliant with SHACL (where `sh:targetClass` does not generate errors, but creates only the link between data and schema), we will remove all errors generated by `sh:targetClass` and will optionally add `sh:class` to the root node, so that we keep the constraint that generates an error. The classes defined in `sh:targetClass` and `sh:class` should be the same.

Example in DS node:

```json
{
  "@type": "ds:DomainSpecification",
  "sh:targetClass": [
    "schema:SkiResort"
  ],
  "sh:class": [
    "schema:SkiResort"
  ],
  ...
}
```

#### 1.4.2. sh:targetObjectsOf

Additionally, `sh:targetObjectsOf` is officially added to the DS specification (see [SHACL specification](https://www.w3.org/TR/shacl/#targetObjectsOf)). In this case, an additional `sh:class` constraint is possible for the DS node. The range of this property is the `@id` of the target property term. An entry is added into the standard `@context` for convenience reasons.

Addition to `@context`:

```json
"@context": {
  ...
  "sh:targetObjectsOf": {
    "@type": "@id"
  },
  ...
}
```

Example in DS node (any entity that is object of the property `schema:address` is seen as a target for this DS):

```json
{
  "@type": "ds:DomainSpecification",
  "sh:targetObjectsOf": "schema:address",
  ...
}
```

#### 1.4.3. sh:targetSubjectsOf

`sh:targetSubjectsOf` is also added to the DS specification (see [SHACL specification](https://www.w3.org/TR/shacl/#targetSubjectsOf)). An additional `sh:class` constraint is possible for the DS node. The range of this property is the `@id` of the target property term. An entry is added into the standard `@context` for convenience reasons.

Addition to `@context`:

```json
"@context": {
  ...
  "sh:targetSubjectsOf": {
    "@type": "@id"
  },
  ...
}
```

Example in DS node (any entity that is subject of the property `schema:address` is seen as a target for this DS):

```json
{
  "@type": "ds:DomainSpecification",
  "sh:targetSubjectsOf": "schema:address",
  ...
}
```

#### 1.4.4. ds:compliesWith

We also adopt `ds:compliesWith` into the DS specification (similar to `sh:shapesGraph`, see [SHACL specification](https://www.w3.org/TR/shacl/#sh-shapes-graph)), which enables a method for entities to specify the Domain Specification(s) to which they comply. The range of this property is the `@id` of the said DS. Keep in mind that this term is not used in Domain Specifications, but in the data (any "Thing" can use the `ds:compliesWith` property). Multiple `ds:compliesWith` assertions are treated as a conjunction (an instance MUST fit all DS defined on it).

Example for a JSON-LD annotation:

```json
{
  "@context": {
    "@vocab":"https://schema.org/",
    "ds": "https://vocab.sti2.at/ds/"
  },
  "@type": "Person",
  "ds:compliesWith": {
    "@id": "https://semantify.it/ds/-fYx5D34d"
  },
  "name": "Jane Doe",
  "jobTitle": "Professor",
  "telephone": "(123) 123-4567",
  "url": "http://www.janedoe.com"
}
```

#### 1.4.5. Class-matching semantics

The class-matching semantics for `sh:targetClass` and `sh:class` have been relaxed, as shown in the following table. The new semantics allow the data to have additional types, that are not stated in the Domain Specification.

|                 | Domain Specification      | Data                                   | Match      |
| --------------- | ------------------------- | -------------------------------------- | ---------- |
|                 | sh:targetClass / sh:class | @type                                  |            |
| exact match     | LodgingBusiness           | LodgingBusiness                        | yes        |
| additional type | LodgingBusiness           | LodgingBusiness, Product               | **yes** \* |
| sub-type        | LodgingBusiness           | Motel                                  | yes        |
| no relation     | LodgingBusiness           | CreativeWork                           | no         |
| exact match     | LodgingBusiness, Product  | LodgingBusiness, Product               | yes        |
| additional type | LodgingBusiness, Product  | LodgingBusiness, Product, CreativeWork | **yes** \* |
| sub-type        | LodgingBusiness, Product  | Hotel, Product                         | yes        |
| not all types   | LodgingBusiness, Product  | LodgingBusiness                        | no         |
| no relation     | LodgingBusiness, Product  | CreativeWork                           | no         |

### 1.5. Update schema:schemaVersion

Schema.org has stopped releasing dedicated pages for new vocabulary versions (see [schema.org GitHub issues](https://github.com/schemaorg/schemaorg/issues/2805)). The old URLs of those pages are not available anymore (e.g. <https://schema.org/version/9.0/>). Those URLs were used for the property `schema:schemaVersion` in Domain Specifications to specify the used schema.org vocabulary version. Since they are not valid anymore, the value of `schema:schemaVersion` must be changed.

The new URLs specified at <https://schema.org/schemaVersion> are not "attractive", therefore the used version is now given as a string (only the version number) instead of an URL, e.g. the previous URL `https://schema.org/version/3.2/` converts to the string `"3.2"`.

Example in DS node:

```json
{
  "@type": "ds:DomainSpecification",
  "schema:schemaVersion": "12.0",
  ...
}
```

#### 1.5.1. Update schema:version

The value type for `schema:version` is changed from double to string. This is done to be more consistent with other version terms (`schema:schemaVersion` and `ds:version`) and to allow further versioning options (e.g. `"1.0.4-beta"`).

Example in DS node:

```json
{
  "@type": "ds:DomainSpecification",
  "schema:version": "1.04",
  ...
}
```

### 1.6. Move sh:class into sh:node

Currently, a property range that defines a certain class has the terms `sh:class` and `sh:node`, where `sh:node` contains a `sh:NodeShape` with `sh:property` defining the properties of that class. We chose this structure to simplify the definition of a "standard class" (the range must have the specified class, but its properties are not constrained, therefore we simply omitted `sh:node`).

In **DS-V7** we want to allow the use of references as ranges, therefore we want to change the structure to have `sh:class` and `sh:property` both inside the `sh:NodeShape` (like in a DS node). This makes the definition of a standard class a little more complex, but it makes it much easier to handle references because we have `sh:class` and `sh:property` at the same level for DS nodes and Class nodes.

Example Class node for a restricted class:

```json
{
  "sh:node": {
    "@type": "sh:NodeShape",
    "sh:class": ["schema:PostalAddress"],
    "sh:property": [
      {
        "@type": "sh:PropertyShape",
        ...
      },
      ...
    ]
  }
}
```

Example Class node for a standard class:

```json
{
  "sh:node": {
    "@type": "sh:NodeShape",
    "sh:class": ["schema:PostalAddress"]
  }
}
```

### 1.7. Move @id of a DS from graph into DS root node

In the raw JSON-LD of a Domain Specification (see example) an `@id` is used to identify the Domain Specification. In theory, the DS itself (the so-called DS node, which is inside the `@graph`) should have the `@id`, and not the outter `@graph` (which is the case at the moment). So far, this has been no problem, but now that we want to use DS references more often (sub-DS, property value is a "copy by reference", etc.), it makes sense to move the `@id` to the correct position.

Example DS in **DS-V5** (`@id` of DS at outmost position):

```json
{
  "@context": {
    ...
  },
  "@graph": [
    {
      "@id": "_:RootNode",
      "@type": "ds:DomainSpecification",
      ...
    }
  ],
  "@id": "https://semantify.it/ds/47tJxjyLE"
}
```

Example DS in **DS-V7** (correct `@id` of DS in DS node):

```json
{
  "@context": {
    ...
  },
  "@graph": [
    {
      "@id": "https://semantify.it/ds/47tJxjyLE",
      "@type": "ds:DomainSpecification",
      ...
    }
  ]
}
```

### 1.8. Bugfix standard @context

In **DS-V7** a minimal `@context` is provided: If a tool or use-case needs further changes to the `@context` they should be done in a pre-processing step. The standard `@context` for **DS-V7** and further explanation can be found in [Context.md](https://gitbook.semantify.it/domainspecifications/ds-v7/grammar/domainspecification/context).

### 1.9. Bugfix terms from the DS vocabulary

During the revision of the DS vocabulary file, we have encountered some terms that we want to change.

Domain Specification:

* `ds:usedVocabularies` is renamed to `ds:usedVocabulary` (this term should only be used if there is at least one external vocabulary used).

Verification Report:

* `ds:errors` is renamed to `ds:error`.

Additionally, the `@context` entry for the DS vocabulary is changed to `https`, resulting in `"ds": "https://vocab.sti2.at/ds/"`.

### 1.10. sh:order becomes deprecated

The term `sh:order` becomes deprecated and is replaced by `ds:propertyDisplayOrder`. ds:propertyDisplayOrder provides a list of property IRIs that reflect the wished display order for the properties of the current Class/DS Node. More details are found in [DomainSpecification.md](https://gitbook.semantify.it/domainspecifications/ds-v7/grammar/domainspecification/domainspecification).

## 2. Additions

### 2.1. ds:version

The new term `ds:version` is used at the DS node level to **specify the DS Specification version** that was used to create the Domain Specification. This information will be important for software parsing Domain Specifications to handle different versions of DS (expected properties, grammar, etc.).

The range of `ds:version` is a string that specifies the used version number with one decimal place, e.g. if the specification is titled "DS-V7", the `ds:version` is `"7.0"`. The decimal place allows us to release minor upgrades to the specification (if wished in the future).

Be careful to not confound this term with other version-terms like `schema:schemaVersion` (the used schema.org vocabulary version) or `schema:version` (the version of the DS itself, which increases on changes of the content).

Example in DS node:

```json
{
  "@type": "ds:DomainSpecification",
  "sh:targetClass": ["schema:SkiResort"],
  "sh:class": ["schema:SkiResort"],
  "ds:version": "7.0",
  "schema:schemaVersion": "12.0",
  "schema:version": "1.06",
  ...
}
```

### 2.2. DataType handling for Language Strings

In **DS-V7** a new datatype is introduced: `rdf:langString`

Until now, we have used `xsd:string` and allowed it to have language tags, which is not possible in theory. With **DS-V7** we do NOT allow `xsd:string` to have language tags anymore (that means this datatype MUST NOT have language-related constraints), and `rdf:langString` is introduced to express a string that MUST have a language tag (the only datatype that CAN have language-related constraints). By language tag, we understand a string representing a language (see the [language tag specification](https://www.rfc-editor.org/rfc/bcp/bcp47.txt)).

For the schema <-> xsd datatype-mapping we use, this means that `schema:Text` is mapped to `xsd:string` if no language tag is allowed, or to `rdf:langString` if a language tag MUST be used. In theory, a DS-Editor could allow the user to add both of these datatype options for `schema:Text` (e.g. to make language tags optional). For the verification, the division of these two data types must be clear.

Example in a Property node (must use a language tag):

```json
{
  "@type": "sh:PropertyShape",
  "sh:path": "schema:description",
  "sh:or": [
    {
      "sh:datatype": "rdf:langString",
      "sh:languageIn": [
        "en",
        "de",
        "es"
      ]
    }
  ],
  ...
}
```

### 2.3. ds:hasLanguage

The new constraint `ds:hasLanguage` specifies that the given set of language tags (see the [language tag specification](https://www.rfc-editor.org/rfc/bcp/bcp47.txt)) MUST be used. This constraint can be used only in a Datatype node with `"sh:datatype": "rdf:langString"`.

Example in a Property node:

```json
{
  "@type": "sh:PropertyShape",
  "sh:path": "schema:description",
  "sh:or": [
    {
      "sh:datatype": "rdf:langString",
      "sh:languageIn": [
        "en",
        "de",
        "es"
      ],
      "ds:hasLanguage": [
        "en",
        "de"
      ],
      "sh:uniqueLang": true
    }
  ]
}
```

In this example, the constraint `sh:languageIn` is used to specify the possible language tags (3). `ds:hasLanguage` specifies the mandatory language tags (2). Additionally, `sh:uniqueLang` is used to specify that each language tag can be used at most one time. In this example, the property `description` must have at least 2 string values, from which one has the language tag `en`, and the other has the language tag `de`. There could be a third string value with the language tag `es`.

### 2.4. ds:defaultLanguage

The new term `ds:defaultLanguage` specifies default language tags for a Datatype node with `"sh:datatype": "rdf:langString"`. This term does not have any effects on the verification result but has only informational character.

Example in a Property node:

```json
{
  "@type": "sh:PropertyShape",
  "sh:path": "schema:name",
  "sh:or": [
    {
      "sh:datatype": "rdf:langString",
      "ds:defaultLanguage": [
        "en"
      ]
    }
  ]
}
```

### 2.5. ds:subDSOf

#### 2.5.1. Syntax

With **DS-V7** the concept of Sub Domain Specifications is introduced. The term `ds:subDSOf` specifies that the Domain Specification is a Sub-DS of the referenced DS (by its `@id`). A Domain Specification can have only one Super-DS but could have multiple Sub-DS.

Example in a DS node:

```json
{
  "@type": "ds:DomainSpecification",
  "sh:targetClass": ["schema:Hotel"],
  "sh:class": ["schema:Hotel"],
  "ds:subDSOf": "https://semantify.it/ds/fBhz5h78s",
  ...
}
```

Addition to the standard `@context`:

```json
"@context": {
  ...
  "ds:subDSOf": {
    "@type": "@id"
  },
  ...
}
```

#### 2.5.2 Semantics

* The constraints defined in a Sub-DS MUST be as restrictive as the Super-DS or more restrictive. In order to be in compliance with a DS that has a Super-DS, a data instance MUST also be compliant to that Super-DS (instances that fit a Sub-DS MUST be a subset of those that fit its Super-DS).
* A Sub-DS can introduce new constraints. This is also possible for already defined constraints, but they MUST be as restrictive as the Super-DS or more restrictive. At the same time the new restrictions must also fit the Super-DS. This is a delicate challenge, e.g.
  * Adding a new PropertyShape makes a Sub-DS more restrictive, but the Super-DS must NOT have `sh:closed true`, in order to allow the Sub-DS to introduce new properties.
  * Adding a new range to an inherited PropertyShape makes a Sub-DS less restrictive.
  * Adding a cardinality constraint (e.g. `sh:maxCount`) to an inherited PropertyShape makes a Sub-DS more restrictive.
  * Increasing the value of an inherited `sh:maxCount` constraint makes a Sub-DS less restrictive.
  * Increasing the value of an inherited `sh:minCount` constraint makes a Sub-DS more restrictive.
  * The `sh:targetClass` of a Sub-DS MUST be the same or a sub-class of the `sh:targetClass` of its Super-DS.
  * Adding additional target classes (MTE) would make a Sub-DS more restrictive.

#### 2.5.3. Implications for the implementation

The most challenging part of this new term is to ensure the consistency between hierarchical DS when creating/editing/deleting Domain Specifications. Tools must aid users to not take actions that result in an invalid `ds:subDSOf` definition.

Tools presenting Domain Specifications should show/link the Super-DS in a prominent way, and/or show the total resulting constraints of a DS and its Super-DS (and recursively their Super-DS). For the verification the total resulting constraints are important. All these tools that read a DS assume that the `ds:subDSOf` link is valid (that the target DS exists and that the semantic rules are followed).

#### 2.5.4. ds:propertyDisplayOrder

The new term `ds:propertyDisplayOrder` is introduced to replace `sh:order` and to provide means to include property terms inherited from the Super-DS. In general, it is recommended to use `ds:propertyDisplayOrder`, the term `sh:order` becomes deprecated. Details about this new property can be found in [DomainSpecification.md](https://gitbook.semantify.it/domainspecifications/ds-v7/grammar/domainspecification/domainspecification).

### 2.6. Use of references

When defining a range for a property it is possible to reference an already created class definition. These class definitions could be taken from the DS that is being created (an inner `sh:NodeShape`), or from an external Domain Specification (their DS node). In any case, the range is given by using the `@id` of the referenced DS/NodeShape.

#### 2.6.1. Internal reference

In order to reference NodeShapes that are part of a DS, those NodeShapes need an IRI. It makes sense to give them the same BaseIRI as the DS in which they are in, with the addition of a **fragment id**, e.g. in the DS with the IRI `https://semantify.it/ds/OBbzsh4_B` there could be a NodeShape with the IRI `https://semantify.it/ds/OBbzsh4_B#DpruH`.

Example Class node (inner NodeShape):

```json
{
  "sh:node": {
    "@id": "https://semantify.it/ds/OBbzsh4_B#DpruH",
    "@type": "sh:NodeShape",
    "sh:class": ["schema:PostalAddress"],
    "sh:property": [
      {
        "@type": "sh:PropertyShape",
        ...
      },
      ...
    ]
  }
}
```

Example Property node that references the previous example Class node:

```json
{
  "@type": "sh:PropertyShape",
  "sh:path": "schema:address",
  "sh:or": [
    {
      "sh:node": {
        "@id": "https://semantify.it/ds/OBbzsh4_B#DpruH"
      }
    }
  ]
}
```

In order to make the use of internal references more convenient, we introduce the following rules:

* Every NodeShape inside a DS receives an IRI, even if it hasn't been referenced yet.
* The NodeShape that specifies the class node (the referenced NodeShape) contains `"@type": "sh:NodeShape"` and all the constraints needed.
* The internal references contain only the `@id` property. They can not add additional constraints.
* Only valid matches can be used as a reference for a range, for this, the `sh:class` constraint of the target NodeShape is checked. If the target class of a NodeShape is `schema:Hotel`, but the property in question can not have that class as a valid range, then that NodeShape can **not** be referenced.
* It is possible to create circular Domain Specifications.

#### 2.6.2. External reference

External references enable the reuse of whole Domain Specifications. To do this, a property range has just to specify the IRI of the external DS.

Example Property node that references an external DS with the IRI `https://semantify.it/ds/OBbd74jf9`:

```json
{
  "@type": "sh:PropertyShape",
  "sh:path": "schema:address",
  "sh:or": [
    {
      "sh:node": {
        "@id": "https://semantify.it/ds/OBbd74jf9"
      }
    }
  ]
}
```

In order to make the use of external references more convenient, we introduce the following rules:

* The external references contain only the `@id` property. They can not add additional constraints.
* Only valid DS matches can be used as a reference for a range, for this the matching mechanics of the external DS are checked (e.g. `sh:targetClass` , `sh:targetObjectsOf`). If the target class of a DS is `schema:Hotel`, but the property in question can not have that class as a valid range, then that DS can **not** be referenced.
* For the verification, the matching mechanics of the external DS are ignored (e.g. `sh:targetClass` , `sh:targetObjectsOf`), only the constraints are important (e.g. `sh:class`, `sh:property`).

### 2.7 sh:closed

See [SHACL specification](https://www.w3.org/TR/shacl/#ClosedConstraintComponent).

The term `sh:closed` can be used in NodeShapes to specify if additional properties (other than the properties allowed by `sh:property`) are allowed or not. In the past, Domain Specifications had `"sh:closed": true` implicitly in all NodeShapes. Now the DS creator should be able to specify the wished behaviour.

Example (the `schema:PostalAddress` entity is allowed to have additional properties that are not specified in `sh:property`):

```json
{
  "sh:node": {
    "@type": "sh:NodeShape",
    "sh:class": ["schema:PostalAddress"],
    "sh:closed": false,
    "sh:property": [
      ...
    ]
  }
}
```
