Graph Normalization
By default, we take steps to normalize Schema-related data into more deterministic shapes and values. To start, structural semantics are evaluated.
- Indirect Class Reference — e.g.
PlayAction
forinteractionType
becomes the type of a nested node - Indirect Literal Property — e.g. text for
audience
becomes thename
property of a nested node - Infer Resource Type — e.g.
PropertyValue
added to an untyped resource of anexifData
property - Expand Quantity — e.g.
1.2 kg
string becomes a co-typedQuantitativeValue
withvalue
,unitCode
- Actions: Expand Short-hand — e.g.
required=true
string becomes aPropertySpecification
resource
Once the structure is evaluated, the following extended validations are also performed.
- Data Types — e.g.
DateTime
properties become compliant ISO 8601 values - Properties — e.g.
telephone
values become a compliant E.164 with optional suffixes
Indirect Class Reference
Specifications currently do not differentiate between references to a Thing vs references to a resource with a type of Thing. By default, we do not emit a validation message and, instead, convert an otherwise-acceptable value into an anonymous resource using the Thing as its type.
Official documentation has used a mix of practices in examples, and it has been briefly mentioned on public GitHub comments as a potential issue (ref, ref).
Learn more from the related validation topic.
Examples
Input | Output |
---|---|
{ "interactionType": "PlayAction" } | { "interactionType": { "@type": "PlayAction" } } |
Indirect Literal Property
Publishers sometimes use a literal value where a resource of a particular type is expected. By default, we do not emit a validation message and, instead, convert an otherwise-acceptable value into an anonymous resource with its equivalent inferred type and properties.
Learn more from the related validation topic.
Examples
Input | Output |
---|---|
{ "audience": "Small businesses" } | { "audience": { "@type": "Audience", "name": "Small businesses" } } |
Infer Resource Type
Publishers sometimes forget to include an explicit type of Thing in resources. In cases where it can be inferred from context (such as constraining ancestor references), we automatically add the appropriate type. In cases where a type cannot be determined for a Schema-based resource, we will add a generic type of Thing.
Examples
Input | Output |
---|---|
{ "exifData": { "name": "FNumber", "value": "f/4.0" } } | { "exifData": { "@type": "PropertyValue" "name": "FNumber", "value": "f/4.0" } } |
{ "brand": { "name": "ACME Widgets" } } | { "brand": { "@type": "Thing", "name": "ACME Widgets" } } |
Expand Quantity
Publishers often use a range of formats and conventions for properties with a Quantity type. As defined by the specification, its schematic usage ranges between a thing and data type, while its value contents is logically closer to a QuantitativeValue. With that in mind, we take the opinionated approach of normalizing quantified units (including Distance, Energy, and Mass) in the following ways:
- Values become an anonymous resource with their type and original value as a
name
property (based on Indirect Literal Property and Infer Resource Type). - Values are evaluated to determine their numeric value and standard units. If successful, the value becomes co-typed with QuantitativeValue and includes the
value
andunitCode
properties.
Examples
Input | Output |
---|---|
{ "distance": "7 ft" } | { "distance": { "@type": [ "Distance", "QuantitativeValue" ], "name": "7 ft", "value": 7, "unitCode": "FOT" } } |
{ "proteinContent": "20" } | { "proteinContent": { "@type": [ "Mass", "QuantitativeValue" ], "name": "20", "value": 20, "unitCode": "GRM" } } |
Actions: Expand Short-hand
Publishers have the option of using a short-hand, textual form or PropertyValueSpecification-type resource when describing Action constraints. We automatically expand textual forms into its PropertyValueSpecification equivalent form.
Examples
Input | Output |
---|---|
{ "query-input": "name=q required=true" } | { "query-input": { "@type": "PropertyValueSpecification", "valueName": "q", "valueRequired": { "@id": "True" } } } |