diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html index 8a46be0fc..ac73997a5 100644 --- a/docs/odata-csdl-json/odata-csdl-json.html +++ b/docs/odata-csdl-json/odata-csdl-json.html @@ -2481,8 +2481,9 @@

14.4.1.1 Path

A model path MAY contain path segments starting with a navigation property, then followed by an at (@) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.

-

Example 65: model path addressing an annotation on a navigation property

-
.../Items@Capabilities.InsertRestrictions/Insertable
+

Example 65: model path addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property

+
.../Items@Core.Description
+
.../Items/@Core.Description

An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.

@@ -2516,11 +2517,11 @@

1

Example 68:

-
"@UI.ReferenceFacet": "Product/Supplier/@UI.LineItem",
-"@UI.CollectionFacet#Contacts": [
-  "Supplier/@Communication.Contact",
-  "Customer/@Communication.Contact"
-]
+
"@UI.ReferenceFacet": "Product/Supplier/@UI.LineItem",
+"@UI.CollectionFacet#Contacts": [
+  "Supplier/@Communication.Contact",
+  "Customer/@Communication.Contact"
+]

14.4.1.4 Model Element Path

The model element path expression provides a value for terms or term properties that specify the built-in type Edm.ModelElementPath. Its argument is a model path.

@@ -2530,7 +2531,7 @@

Example 69:

-
"@org.example.MyFavoriteModelElement": "/self.someAction"
+
"@org.example.MyFavoriteModelElement": "/self.someAction"

14.4.1.5 Navigation Property Path

The navigation property path expression provides a value for terms or term properties that specify the built-in types Edm.NavigationPropertyPath, Edm.AnyPropertyPath, or Edm.ModelElementPath. Its argument is a model path with the following restriction:

@@ -2543,14 +2544,14 @@

Example 70:

-
"@UI.HyperLink": "Supplier",
-
-"@Capabilities.UpdateRestrictions": {
-  "NonUpdatableNavigationProperties": [
-    "Supplier",
-    "Category"
-  ]
-}
+
"@UI.HyperLink": "Supplier",
+
+"@Capabilities.UpdateRestrictions": {
+  "NonUpdatableNavigationProperties": [
+    "Supplier",
+    "Category"
+  ]
+}

14.4.1.6 Property Path

The property path expression provides a value for terms or term properties that specify one of the built-in types Edm.PropertyPath, Edm.AnyPropertyPath, or Edm.ModelElementPath. Its argument is a model path with the following restriction:

@@ -2563,14 +2564,14 @@

14.4.1.

Example 71:

-
"@UI.RefreshOnChangeOf": "ChangedAt",
-
-"@Capabilities.UpdateRestrictions": {
-  "NonUpdatableProperties": [
-    "CreatedAt",
-    "ChangedAt"
-  ]
-}
+
"@UI.RefreshOnChangeOf": "ChangedAt",
+
+"@Capabilities.UpdateRestrictions": {
+  "NonUpdatableProperties": [
+    "CreatedAt",
+    "ChangedAt"
+  ]
+}

14.4.1.7 Value Path

The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.

@@ -2581,13 +2582,13 @@

$Path

Example 72:

-
"@UI.DisplayName": {
-  "$Path": "FirstName"
-},
-
-"@UI.DisplayName#second": {
-  "$Path": "@vCard.Address#work/FullName"
-}
+
"@UI.DisplayName": {
+  "$Path": "FirstName"
+},
+
+"@UI.DisplayName#second": {
+  "$Path": "@vCard.Address#work/FullName"
+}

14.4.2 Comparison and Logical Operators

Annotations MAY use the following logical and comparison expressions which evaluate to a Boolean value. These expressions MAY be combined and they MAY be used anywhere instead of a Boolean expression.

@@ -2668,98 +2669,98 @@

Example 73:

-
{
-  "$And": [
-    {
-      "$Path": "IsMale"
-    },
-    {
-      "$Path": "IsMarried"
-    }
-  ]
-},
-{
-  "$Or": [
-    {
-      "$Path": "IsMale"
-    },
-    {
-      "$Path": "IsMarried"
-    }
-  ]
-},
-{
-  "$Not": {
-    "$Path": "IsMale"
-  }
-},
-{
-  "$Eq": [
-    null,
-    {
-      "$Path": "IsMale"
-    }
-  ]
-},
-{
-  "$Ne": [
-    null,
-    {
-      "$Path": "IsMale"
-    }
-  ]
-},
-{
-  "$Gt": [
-    {
-      "$Path": "Price"
-    },
-    20
-  ]
-},
-{
-  "$Ge": [
-    {
-      "$Path": "Price"
-    },
-    10
-  ]
-},
-{
-  "$Lt": [
-    {
-      "$Path": "Price"
-    },
-    20
-  ]
-},
-{
-  "$Le": [
-    {
-      "$Path": "Price"
-    },
-    100
-  ]
-},
-{
-  "$Has": [
-    {
-      "$Path": "Fabric"
-    },
-    "Red"
-  ]
-},
-{
-  "$In": [
-    {
-      "$Path": "Size"
-    },
-    [
-      "XS",
-      "S"
-    ]
-  ]
-} ```
+
{
+  "$And": [
+    {
+      "$Path": "IsMale"
+    },
+    {
+      "$Path": "IsMarried"
+    }
+  ]
+},
+{
+  "$Or": [
+    {
+      "$Path": "IsMale"
+    },
+    {
+      "$Path": "IsMarried"
+    }
+  ]
+},
+{
+  "$Not": {
+    "$Path": "IsMale"
+  }
+},
+{
+  "$Eq": [
+    null,
+    {
+      "$Path": "IsMale"
+    }
+  ]
+},
+{
+  "$Ne": [
+    null,
+    {
+      "$Path": "IsMale"
+    }
+  ]
+},
+{
+  "$Gt": [
+    {
+      "$Path": "Price"
+    },
+    20
+  ]
+},
+{
+  "$Ge": [
+    {
+      "$Path": "Price"
+    },
+    10
+  ]
+},
+{
+  "$Lt": [
+    {
+      "$Path": "Price"
+    },
+    20
+  ]
+},
+{
+  "$Le": [
+    {
+      "$Path": "Price"
+    },
+    100
+  ]
+},
+{
+  "$Has": [
+    {
+      "$Path": "Fabric"
+    },
+    "Red"
+  ]
+},
+{
+  "$In": [
+    {
+      "$Path": "Size"
+    },
+    [
+      "XS",
+      "S"
+    ]
+  ]
+} ```

14.4.3 Arithmetic Operators

Annotations MAY use the following arithmetic expressions which evaluate to a numeric value. These expressions MAY be combined, and they MAY be used anywhere instead of a numeric expression of the appropriate type. The semantics and evaluation rules for each arithmetic expression is identical to the corresponding arithmetic operator defined in OData-URL.

@@ -2812,71 +2813,71 @@

Example 74:

-
{
-  "$Add": [
-    {
-      "$Path": "StartDate"
-    },
-    {
-      "$Path": "Duration"
-    }
-  ]
-},
-{
-  "$Sub": [
-    {
-      "$Path": "Revenue"
-    },
-    {
-      "$Path": "Cost"
-    }
-  ]
-},
-{
-  "$Neg": {
-    "$Path": "Height"
-  }
-},
-{
-  "$Mul": [
-    {
-      "$Path": "NetPrice"
-    },
-    {
-      "$Path": "TaxRate"
-    }
-  ]
-},
-{
-  "$Div": [
-    {
-      "$Path": "Quantity"
-    },
-    {
-      "$Path": "QuantityPerParcel"
-    }
-  ]
-},
-{
-  "$DivBy": [
-    {
-      "$Path": "Quantity"
-    },
-    {
-      "$Path": "QuantityPerParcel"
-    }
-  ]
-},
-{
-  "$Mod": [
-    {
-      "$Path": "Quantity"
-    },
-    {
-      "$Path": "QuantityPerParcel"
-    }
-  ]
-}
+
{
+  "$Add": [
+    {
+      "$Path": "StartDate"
+    },
+    {
+      "$Path": "Duration"
+    }
+  ]
+},
+{
+  "$Sub": [
+    {
+      "$Path": "Revenue"
+    },
+    {
+      "$Path": "Cost"
+    }
+  ]
+},
+{
+  "$Neg": {
+    "$Path": "Height"
+  }
+},
+{
+  "$Mul": [
+    {
+      "$Path": "NetPrice"
+    },
+    {
+      "$Path": "TaxRate"
+    }
+  ]
+},
+{
+  "$Div": [
+    {
+      "$Path": "Quantity"
+    },
+    {
+      "$Path": "QuantityPerParcel"
+    }
+  ]
+},
+{
+  "$DivBy": [
+    {
+      "$Path": "Quantity"
+    },
+    {
+      "$Path": "QuantityPerParcel"
+    }
+  ]
+},
+{
+  "$Mod": [
+    {
+      "$Path": "Quantity"
+    },
+    {
+      "$Path": "QuantityPerParcel"
+    }
+  ]
+}

14.4.4 Apply Client-Side Functions

The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function.

@@ -2891,24 +2892,24 @@

OData-ABNF, i.e. Edm.Binary as binaryValue, Edm.Boolean as booleanValue etc.

Example 75:

-
"@UI.DisplayName": {
-  "$Apply": [
-    "Product: ",
-    {
-      "$Path": "ProductName"
-    },
-    " (",
-    {
-      "$Path": "Available/Quantity"
-    },
-    " ",
-    {
-      "$Path": "Available/Unit"
-    },
-    " available)"
-  ],
-  "$Function": "odata.concat"
-}
+
"@UI.DisplayName": {
+  "$Apply": [
+    "Product: ",
+    {
+      "$Path": "ProductName"
+    },
+    " (",
+    {
+      "$Path": "Available/Quantity"
+    },
+    " ",
+    {
+      "$Path": "Available/Unit"
+    },
+    " available)"
+  ],
+  "$Function": "odata.concat"
+}

ProductName is of type String, Quantity in complex type Available is of type Decimal, and Unit in Available is of type enumeration, so the result of the Path expression is represented as the member name of the enumeration value.

14.4.4.2 Function odata.fillUriTemplate

@@ -2920,55 +2921,55 @@

labeled element expressions that evaluate to a collection of complex types with two properties that are used in lexicographic order. The first property is used as key, the second property as value.

Example 76: assuming there are no special characters in values of the Name property of the Actor entity

-
  "$Apply": [
-    "http://host/someAPI/Actors/{actorName}/CV",
-    {
-      "$LabeledElement": {
-        "$Path": "Actor/Name"
-      },
-      "$Name": "self.actorName"
-    }
-  ],
-  "$Function": "odata.fillUriTemplate"
-}
+
  "$Apply": [
+    "http://host/someAPI/Actors/{actorName}/CV",
+    {
+      "$LabeledElement": {
+        "$Path": "Actor/Name"
+      },
+      "$Name": "self.actorName"
+    }
+  ],
+  "$Function": "odata.fillUriTemplate"
+}

14.4.4.3 Function odata.matchesPattern

The odata.matchesPattern client-side function takes two string expressions as arguments and returns a Boolean value.

The function returns true if the second expression evaluates to an ECMAScript (JavaScript) regular expression and the result of the first argument expression matches that regular expression, using syntax and semantics of ECMAScript regular expressions.

Example 77: all non-empty FirstName values not containing the letters b, c, or d evaluate to true

-
{
-  "$Apply": [
-    {
-      "$Path": "FirstName"
-    },
-    "^[^b-d]+$"
-  ],
-  "$Function": "odata.matchesPattern"
-}
+
{
+  "$Apply": [
+    {
+      "$Path": "FirstName"
+    },
+    "^[^b-d]+$"
+  ],
+  "$Function": "odata.matchesPattern"
+}

14.4.4.4 Function odata.uriEncode

The odata.uriEncode client-side function takes one argument of primitive type and returns the URL-encoded OData literal that can be used as a key value in OData URLs or in the query part of OData URLs.

Note: string literals are surrounded by single quotes as required by the paren-style key syntax.

Example 78:

-
{
-  "$Apply": [
-    "http://host/service/Genres({genreName})",
-    {
-      "$LabeledElement": {
-        "$Apply": [
-          {
-            "$Path": "NameOfMovieGenre"
-          }
-        ],
-        "$Function": "odata.uriEncode"
-      },
-      "$Name": "self.genreName"
-    }
-  ],
-  "$Function": "odata.fillUriTemplate"
-}
+
{
+  "$Apply": [
+    "http://host/service/Genres({genreName})",
+    {
+      "$LabeledElement": {
+        "$Apply": [
+          {
+            "$Path": "NameOfMovieGenre"
+          }
+        ],
+        "$Function": "odata.uriEncode"
+      },
+      "$Name": "self.genreName"
+    }
+  ],
+  "$Function": "odata.fillUriTemplate"
+}

14.4.5 Cast

The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the cast canonical function defined in OData-URL.

@@ -2980,12 +2981,12 @@

$Cast

Example 79:

-
"@UI.Threshold": {
-  "$Cast": {
-    "$Path": "Average"
-  },
-  "$Type": "Edm.Decimal"
-}
+
"@UI.Threshold": {
+  "$Cast": {
+    "$Path": "Average"
+  },
+  "$Type": "Edm.Decimal"
+}

14.4.6 Collection

The collection expression enables a value to be obtained from zero or more item expressions. The value calculated by the collection expression is the collection of the values calculated by each of the item expressions. The values of the child expressions MUST all be type compatible.

@@ -2994,11 +2995,11 @@

14.4.6 Collecti

Example 80:

-
"@seo.SeoTerms": [
-  "Product",
-  "Supplier",
-  "Customer"
-]
+
"@seo.SeoTerms": [
+  "Product",
+  "Supplier",
+  "Customer"
+]

14.4.7 If-Then-Else

The if-then-else expression enables a value to be obtained by evaluating a condition expression. It MUST contain exactly three child expressions. There is one exception to this rule: if and only if the if-then-else expression is an item of a collection expression, the third child expression MAY be omitted, reducing it to an if-then expression. This can be used to conditionally add an element to a collection.

@@ -3012,15 +3013,15 @@

$If

Example 81: the condition is a value path expression referencing the Boolean property IsFemale, whose value then determines the value of the $If expression (or so it was long ago)

-
"@person.Gender": {
-  "$If": [
-    {
-      "$Path": "IsFemale"
-    },
-    "Female",
-    "Male"
-  ]
-}
+
"@person.Gender": {
+  "$If": [
+    {
+      "$Path": "IsFemale"
+    },
+    "Female",
+    "Male"
+  ]
+}

14.4.8 Is-Of

The is-of expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true if the child expression returns a type that is compatible with the specified type, and false otherwise.

@@ -3032,12 +3033,12 @@

$IsOf

Example 82:

-
"@Self.IsPreferredCustomer": {
-  "$IsOf": {
-    "$Path": "Customer"
-  },
-  "$Type": "self.PreferredCustomer"
-}
+
"@Self.IsPreferredCustomer": {
+  "$IsOf": {
+    "$Path": "Customer"
+  },
+  "$Type": "self.PreferredCustomer"
+}

14.4.9 Labeled Element

The labeled element expression assigns a name to its single child expression. The value of the child expression can then be reused elsewhere with a labeled element reference expression.

@@ -3050,12 +3051,12 @@

$LabeledEle

Example 83:

-
"@UI.DisplayName": {
-  "$LabeledElement": {
-    "$Path": "FirstName"
-  },
-  "$Name": "CustomerFirstName"
-}
+
"@UI.DisplayName": {
+  "$LabeledElement": {
+    "$Path": "FirstName"
+  },
+  "$Name": "CustomerFirstName"
+}

14.4.10 Labeled Element Reference

The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value.

@@ -3065,9 +3066,9 @@

Example 84:

-
"@UI.DisplayName": {
-  "$LabeledElementReference": "self.CustomerFirstName"
-}
+
"@UI.DisplayName": {
+  "$LabeledElementReference": "self.CustomerFirstName"
+}

14.4.11 Null

The null expression indicates the absence of a value. The null expression MAY be annotated.

@@ -3076,7 +3077,7 @@

14.4.11 Null

Example 85:

-
"@UI.DisplayName": null,
+
"@UI.DisplayName": null,

$Null

@@ -3084,10 +3085,10 @@

$Null

Example 86:

-
"@UI.Address": {
-  "$Null": null,
-  "@self.Reason": "Private"
-}
+
"@UI.Address": {
+  "$Null": null,
+  "@self.Reason": "Private"
+}

14.4.12 Record

The record expression enables a new entity type or complex type instance to be constructed.

@@ -3101,34 +3102,34 @@

14.4.12 Record

Example 87: this annotation "morphs" the entity type from example 8 into a structured type with two structural properties GivenName and Surname and two navigation properties DirectSupervisor and CostCenter. The first three properties simply rename properties of the annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service

-
"@person.Employee": {
-  "@type": "https://example.org/vocabs/person#org.example.person.Manager",
-  "@Core.Description": "Annotation on record",
-  "GivenName": {
-    "$Path": "FirstName"
-  },
-  "GivenName@Core.Description": "Annotation on record member",
-  "Surname": {
-    "$Path": "LastName"
-  },
-  "DirectSupervisor": {
-    "$Path": "Manager"
-  },
-  "CostCenter": {
-    "$UrlRef": {
-      "$Apply": [
-        "http://host/anotherservice/CostCenters('{ccid}')",
-        {
-          "$LabeledElement": {
-            "$Path": "CostCenterID"
-          },
-          "$Name": "ccid"
-        }
-      ],
-      "$Function": "odata.fillUriTemplate"
-    }
-  }
-}
+
"@person.Employee": {
+  "@type": "https://example.org/vocabs/person#org.example.person.Manager",
+  "@Core.Description": "Annotation on record",
+  "GivenName": {
+    "$Path": "FirstName"
+  },
+  "GivenName@Core.Description": "Annotation on record member",
+  "Surname": {
+    "$Path": "LastName"
+  },
+  "DirectSupervisor": {
+    "$Path": "Manager"
+  },
+  "CostCenter": {
+    "$UrlRef": {
+      "$Apply": [
+        "http://host/anotherservice/CostCenters('{ccid}')",
+        {
+          "$LabeledElement": {
+            "$Path": "CostCenterID"
+          },
+          "$Name": "ccid"
+        }
+      ],
+      "$Function": "odata.fillUriTemplate"
+    }
+  }
+}

14.4.13 URL Reference

The URL reference expression enables a value to be obtained by sending a GET request.

@@ -3141,29 +3142,29 @@

$UrlRef

Example 88:

-
"@org.example.person.Supplier": {
-  "$UrlRef": {
-    "$Apply": [
-      "http://host/service/Suppliers({suppID})",
-      {
-        "$LabeledElement": {
-          "$Apply": [
-            {
-              "$Path": "SupplierId"
-            }
-          ],
-          "$Function": "odata.uriEncode"
-        },
-        "$Name": "suppID"
-      }
-    ],
-    "$Function": "odata.fillUriTemplate"
-  }
-},
- 
-"@Core.LongDescription#element": {
-  "$UrlRef": "http://host/wiki/HowToUse"
-}
+
"@org.example.person.Supplier": {
+  "$UrlRef": {
+    "$Apply": [
+      "http://host/service/Suppliers({suppID})",
+      {
+        "$LabeledElement": {
+          "$Apply": [
+            {
+              "$Path": "SupplierId"
+            }
+          ],
+          "$Function": "odata.uriEncode"
+        },
+        "$Name": "suppID"
+      }
+    ],
+    "$Function": "odata.fillUriTemplate"
+  }
+},
+ 
+"@Core.LongDescription#element": {
+  "$UrlRef": "http://host/wiki/HowToUse"
+}

15 Identifier and Path Values

@@ -3201,271 +3202,271 @@

16 CSDL Ex

16.1 Products and Categories Example

Example 90:

-
{
-  "$Version": "4.0",
-  "$EntityContainer": "ODataDemo.DemoService",
-  "$Reference": {
-    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
-      "$Include": [
-        {
-          "$Namespace": "Org.OData.Core.V1",
-          "$Alias": "Core",
-          "@Core.DefaultNamespace": true
-        }
-      ]
-    },
-    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
-      "$Include": [
-        {
-          "$Namespace": "Org.OData.Measures.V1",
-          "$Alias": "Measures"
-        }
-      ]
-    }
-  },
-  "ODataDemo": {
-    "$Alias": "self",
-    "@Core.DefaultNamespace": true,
-    "Product": {
-      "$Kind": "EntityType",
-      "$HasStream": true,
-      "$Key": [
-        "ID"
-      ],
-      "ID": {},
-      "Description": {
-        "$Nullable": true,
-        "@Core.IsLanguageDependent": true
-      },
-      "ReleaseDate": {
-        "$Nullable": true,
-        "$Type": "Edm.Date"
-      },
-      "DiscontinuedDate": {
-        "$Nullable": true,
-        "$Type": "Edm.Date"
-      },
-      "Rating": {
-        "$Nullable": true,
-        "$Type": "Edm.Int32"
-      },
-      "Price": {
-        "$Nullable": true,
-        "$Type": "Edm.Decimal",
-        "@Measures.ISOCurrency": {
-          "$Path": "Currency"
-        }
-      },
-      "Currency": {
-        "$Nullable": true,
-        "$MaxLength": 3
-      },
-      "Category": {
-        "$Kind": "NavigationProperty",
-        "$Type": "self.Category",
-        "$Partner": "Products"
-      },
-      "Supplier": {
-        "$Kind": "NavigationProperty",
-        "$Nullable": true,
-        "$Type": "self.Supplier",
-        "$Partner": "Products"
-      }
-    },
-    "Category": {
-      "$Kind": "EntityType",
-      "$Key": [
-        "ID"
-      ],
-      "ID": {
-        "$Type": "Edm.Int32"
-      },
-      "Name": {
-        "@Core.IsLanguageDependent": true
-      },
-      "Products": {
-        "$Kind": "NavigationProperty",
-        "$Partner": "Category",
-        "$Collection": true,
-        "$Type": "self.Product",
-        "$OnDelete": "Cascade"
-      }
-    },
-    "Supplier": {
-      "$Kind": "EntityType",
-      "$Key": [
-        "ID"
-      ],
-      "ID": {},
-      "Name": {
-        "$Nullable": true
-      },
-      "Address": {
-        "$Type": "self.Address"
-      },
-      "Concurrency": {
-        "$Type": "Edm.Int32"
-      },
-      "Products": {
-        "$Kind": "NavigationProperty",
-        "$Partner": "Supplier",
-        "$Collection": true,
-        "$Type": "self.Product"
-      }
-    },
-    "Country": {
-      "$Kind": "EntityType",
-      "$Key": [
-        "Code"
-      ],
-      "Code": {
-        "$MaxLength": 2
-      },
-      "Name": {
-        "$Nullable": true
-      }
-    },
-    "Address": {
-      "$Kind": "ComplexType",
-      "Street": {
-        "$Nullable": true
-      },
-      "City": {
-        "$Nullable": true
-      },
-      "State": {
-        "$Nullable": true
-      },
-      "ZipCode": {
-        "$Nullable": true
-      },
-      "CountryName": {
-        "$Nullable": true
-      },
-      "Country": {
-        "$Kind": "NavigationProperty",
-        "$Nullable": true,
-        "$Type": "self.Country",
-        "$ReferentialConstraint": {
-          "CountryName": "Name"
-        }
-      }
-    },
-    "ProductsByRating": [
-      {
-        "$Kind": "Function",
-        "$Parameter": [
-          {
-            "$Name": "Rating",
-            "$Nullable": true,
-            "$Type": "Edm.Int32"
-          }
-        ],
-        "$ReturnType": {
-          "$Collection": true,
-          "$Type": "self.Product"
-        }
-      }
-    ],
-    "DemoService": {
-      "$Kind": "EntityContainer",
-      "Products": {
-        "$Collection": true,
-        "$Type": "self.Product",
-        "$NavigationPropertyBinding": {
-          "Category": "Categories"
-        }
-      },
-      "Categories": {
-        "$Collection": true,
-        "$Type": "self.Category",
-        "$NavigationPropertyBinding": {
-          "Products": "Products"
-        },
-        "@Core.Description": "Product Categories"
-      },
-      "Suppliers": {
-        "$Collection": true,
-        "$Type": "self.Supplier",
-        "$NavigationPropertyBinding": {
-          "Products": "Products",
-          "Address/Country": "Countries"
-        },
-        "@Core.OptimisticConcurrency": [
-          "Concurrency"
-        ]
-      },
-      "Countries": {
-        "$Collection": true,
-        "$Type": "self.Country"
-      },
-      "MainSupplier": {
-        "$Type": "self.Supplier",
-        "$NavigationPropertyBinding": {
-          "Products": "Products"
-        },
-        "@Core.Description": "Primary Supplier"
-      },
-      "ProductsByRating": {
-        "$EntitySet": "Products",
-        "$Function": "self.ProductsByRating"
-      }
-    }
-  }
-}
+
{
+  "$Version": "4.0",
+  "$EntityContainer": "ODataDemo.DemoService",
+  "$Reference": {
+    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
+      "$Include": [
+        {
+          "$Namespace": "Org.OData.Core.V1",
+          "$Alias": "Core",
+          "@Core.DefaultNamespace": true
+        }
+      ]
+    },
+    "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
+      "$Include": [
+        {
+          "$Namespace": "Org.OData.Measures.V1",
+          "$Alias": "Measures"
+        }
+      ]
+    }
+  },
+  "ODataDemo": {
+    "$Alias": "self",
+    "@Core.DefaultNamespace": true,
+    "Product": {
+      "$Kind": "EntityType",
+      "$HasStream": true,
+      "$Key": [
+        "ID"
+      ],
+      "ID": {},
+      "Description": {
+        "$Nullable": true,
+        "@Core.IsLanguageDependent": true
+      },
+      "ReleaseDate": {
+        "$Nullable": true,
+        "$Type": "Edm.Date"
+      },
+      "DiscontinuedDate": {
+        "$Nullable": true,
+        "$Type": "Edm.Date"
+      },
+      "Rating": {
+        "$Nullable": true,
+        "$Type": "Edm.Int32"
+      },
+      "Price": {
+        "$Nullable": true,
+        "$Type": "Edm.Decimal",
+        "@Measures.ISOCurrency": {
+          "$Path": "Currency"
+        }
+      },
+      "Currency": {
+        "$Nullable": true,
+        "$MaxLength": 3
+      },
+      "Category": {
+        "$Kind": "NavigationProperty",
+        "$Type": "self.Category",
+        "$Partner": "Products"
+      },
+      "Supplier": {
+        "$Kind": "NavigationProperty",
+        "$Nullable": true,
+        "$Type": "self.Supplier",
+        "$Partner": "Products"
+      }
+    },
+    "Category": {
+      "$Kind": "EntityType",
+      "$Key": [
+        "ID"
+      ],
+      "ID": {
+        "$Type": "Edm.Int32"
+      },
+      "Name": {
+        "@Core.IsLanguageDependent": true
+      },
+      "Products": {
+        "$Kind": "NavigationProperty",
+        "$Partner": "Category",
+        "$Collection": true,
+        "$Type": "self.Product",
+        "$OnDelete": "Cascade"
+      }
+    },
+    "Supplier": {
+      "$Kind": "EntityType",
+      "$Key": [
+        "ID"
+      ],
+      "ID": {},
+      "Name": {
+        "$Nullable": true
+      },
+      "Address": {
+        "$Type": "self.Address"
+      },
+      "Concurrency": {
+        "$Type": "Edm.Int32"
+      },
+      "Products": {
+        "$Kind": "NavigationProperty",
+        "$Partner": "Supplier",
+        "$Collection": true,
+        "$Type": "self.Product"
+      }
+    },
+    "Country": {
+      "$Kind": "EntityType",
+      "$Key": [
+        "Code"
+      ],
+      "Code": {
+        "$MaxLength": 2
+      },
+      "Name": {
+        "$Nullable": true
+      }
+    },
+    "Address": {
+      "$Kind": "ComplexType",
+      "Street": {
+        "$Nullable": true
+      },
+      "City": {
+        "$Nullable": true
+      },
+      "State": {
+        "$Nullable": true
+      },
+      "ZipCode": {
+        "$Nullable": true
+      },
+      "CountryName": {
+        "$Nullable": true
+      },
+      "Country": {
+        "$Kind": "NavigationProperty",
+        "$Nullable": true,
+        "$Type": "self.Country",
+        "$ReferentialConstraint": {
+          "CountryName": "Name"
+        }
+      }
+    },
+    "ProductsByRating": [
+      {
+        "$Kind": "Function",
+        "$Parameter": [
+          {
+            "$Name": "Rating",
+            "$Nullable": true,
+            "$Type": "Edm.Int32"
+          }
+        ],
+        "$ReturnType": {
+          "$Collection": true,
+          "$Type": "self.Product"
+        }
+      }
+    ],
+    "DemoService": {
+      "$Kind": "EntityContainer",
+      "Products": {
+        "$Collection": true,
+        "$Type": "self.Product",
+        "$NavigationPropertyBinding": {
+          "Category": "Categories"
+        }
+      },
+      "Categories": {
+        "$Collection": true,
+        "$Type": "self.Category",
+        "$NavigationPropertyBinding": {
+          "Products": "Products"
+        },
+        "@Core.Description": "Product Categories"
+      },
+      "Suppliers": {
+        "$Collection": true,
+        "$Type": "self.Supplier",
+        "$NavigationPropertyBinding": {
+          "Products": "Products",
+          "Address/Country": "Countries"
+        },
+        "@Core.OptimisticConcurrency": [
+          "Concurrency"
+        ]
+      },
+      "Countries": {
+        "$Collection": true,
+        "$Type": "self.Country"
+      },
+      "MainSupplier": {
+        "$Type": "self.Supplier",
+        "$NavigationPropertyBinding": {
+          "Products": "Products"
+        },
+        "@Core.Description": "Primary Supplier"
+      },
+      "ProductsByRating": {
+        "$EntitySet": "Products",
+        "$Function": "self.ProductsByRating"
+      }
+    }
+  }
+}

16.2 Annotations for Products and Categories Example

Example 91:

-
{
-  "$Version": "4.01",
-  "$Reference": {
-    "http://host/service/$metadata": {
-      "$Include": [
-        {
-          "$Namespace": "ODataDemo",
-          "$Alias": "target"
-        }
-      ]
-    },
-    "http://somewhere/Vocabulary/V1": {
-      "$Include": [
-        {
-          "$Namespace": "Some.Vocabulary.V1",
-          "$Alias": "Vocabulary1"
-        }
-      ]
-    }
-  },
-  "External.Annotations": {
-    "$Annotations": {
-      "target.Supplier": {
-        "@Vocabulary1.EMail": null,
-        "@Vocabulary1.AccountID": {
-          "$Path": "ID"
-        },
-        "@Vocabulary1.Title": "Supplier Info",
-        "@Vocabulary1.DisplayName": {
-          "$Apply": [
-            {
-              "$Path": "Name"
-            },
-            " in ",
-            {
-              "$Path": "Address/CountryName"
-            }
-          ],
-          "$Function": "odata.concat"
-        }
-      },
-      "target.Product": {
-        "@Vocabulary1.Tags": [
-          "MasterData"
-        ]
-      }
-    }
-  }
-} ```
+
{
+  "$Version": "4.01",
+  "$Reference": {
+    "http://host/service/$metadata": {
+      "$Include": [
+        {
+          "$Namespace": "ODataDemo",
+          "$Alias": "target"
+        }
+      ]
+    },
+    "http://somewhere/Vocabulary/V1": {
+      "$Include": [
+        {
+          "$Namespace": "Some.Vocabulary.V1",
+          "$Alias": "Vocabulary1"
+        }
+      ]
+    }
+  },
+  "External.Annotations": {
+    "$Annotations": {
+      "target.Supplier": {
+        "@Vocabulary1.EMail": null,
+        "@Vocabulary1.AccountID": {
+          "$Path": "ID"
+        },
+        "@Vocabulary1.Title": "Supplier Info",
+        "@Vocabulary1.DisplayName": {
+          "$Apply": [
+            {
+              "$Path": "Name"
+            },
+            " in ",
+            {
+              "$Path": "Address/CountryName"
+            }
+          ],
+          "$Function": "odata.concat"
+        }
+      },
+      "target.Product": {
+        "@Vocabulary1.Tags": [
+          "MasterData"
+        ]
+      }
+    }
+  }
+} ```

17 Conformance

diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md index 363945f4a..be54b1b69 100644 --- a/docs/odata-csdl-json/odata-csdl-json.md +++ b/docs/odata-csdl-json/odata-csdl-json.md @@ -4334,8 +4334,13 @@ segment](#TermCast). ::: example Example 65: model path addressing an annotation on a navigation property +vs. term cast addressing an annotation on the resource addressed by the navigation property ``` -.../Items@Capabilities.InsertRestrictions/Insertable +.../Items@Core.Description +``` + +``` +.../Items/@Core.Description ``` ::: diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html index fd7be17a1..af56f1447 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.html +++ b/docs/odata-csdl-xml/odata-csdl-xml.html @@ -2349,8 +2349,9 @@

14.4.1.1 Path

A model path MAY contain path segments starting with a navigation property, then followed by an at (@) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.

-

Example 64: model path addressing an annotation on a navigation property

-
.../Items@Capabilities.InsertRestrictions/Insertable
+

Example 64: model path addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property

+
.../Items@Core.Description
+
.../Items/@Core.Description

An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.

@@ -2385,15 +2386,15 @@

Example 67:

-
<Annotation Term="UI.ReferenceFacet"
-            AnnotationPath="Product/Supplier/@UI.LineItem" />
-
-<Annotation Term="UI.CollectionFacet" Qualifier="Contacts">
-  <Collection>
-    <AnnotationPath>Supplier/@Communication.Contact</AnnotationPath>
-    <AnnotationPath>Customer/@Communication.Contact</AnnotationPath>
-  </Collection>
-</Annotation>
+
<Annotation Term="UI.ReferenceFacet"
+            AnnotationPath="Product/Supplier/@UI.LineItem" />
+
+<Annotation Term="UI.CollectionFacet" Qualifier="Contacts">
+  <Collection>
+    <AnnotationPath>Supplier/@Communication.Contact</AnnotationPath>
+    <AnnotationPath>Customer/@Communication.Contact</AnnotationPath>
+  </Collection>
+</Annotation>

14.4.1.4 Model Element Path

The model element path expression provides a value for terms or term properties that specify the built-in type Edm.ModelElementPath. Its argument is a model path.

@@ -2404,12 +2405,12 @@

Example 68:

-
<Annotation Term="org.example.MyFavoriteModelElement"
-            ModelElementPath="/org.example.someAction" />
-
-<Annotation Term="org.example.MyFavoriteModelElement">
-  <ModelElementPath>/org.example.someAction</ModelElementPath>
-</Annotation>
+
<Annotation Term="org.example.MyFavoriteModelElement"
+            ModelElementPath="/org.example.someAction" />
+
+<Annotation Term="org.example.MyFavoriteModelElement">
+  <ModelElementPath>/org.example.someAction</ModelElementPath>
+</Annotation>

14.4.1.5 Navigation Property Path

The navigation property path expression provides a value for terms or term properties that specify the built-in types Edm.NavigationPropertyPath, Edm.AnyPropertyPath, or Edm.ModelElementPath. Its argument is a model path with the following restriction:

@@ -2423,18 +2424,18 @@

Example 69:

-
<Annotation Term="UI.HyperLink" NavigationPropertyPath="Supplier" />
-
-<Annotation Term="Capabilities.UpdateRestrictions">
-  <Record>
-    <PropertyValue Property="NonUpdatableNavigationProperties">
-      <Collection>
-        <NavigationPropertyPath>Supplier</NavigationPropertyPath>
-        <NavigationPropertyPath>Category</NavigationPropertyPath>
-      </Collection>
-    </PropertyValue>
-  </Record>
-</Annotation>
+
<Annotation Term="UI.HyperLink" NavigationPropertyPath="Supplier" />
+
+<Annotation Term="Capabilities.UpdateRestrictions">
+  <Record>
+    <PropertyValue Property="NonUpdatableNavigationProperties">
+      <Collection>
+        <NavigationPropertyPath>Supplier</NavigationPropertyPath>
+        <NavigationPropertyPath>Category</NavigationPropertyPath>
+      </Collection>
+    </PropertyValue>
+  </Record>
+</Annotation>

14.4.1.6 Property Path

The property path expression provides a value for terms or term properties that specify one of the built-in types Edm.PropertyPath, Edm.AnyPropertyPath, or Edm.ModelElementPath. Its argument is a model path with the following restriction:

@@ -2448,18 +2449,18 @@

E

Example 70:

-
<Annotation Term="UI.RefreshOnChangeOf" PropertyPath="ChangedAt" />
-
-<Annotation Term="Capabilities.UpdateRestrictions">
-  <Record>
-    <PropertyValue Property="NonUpdatableProperties">
-      <Collection>
-        <PropertyPath>CreatedAt</PropertyPath>
-        <PropertyPath>ChangedAt</PropertyPath>
-      </Collection>
-    </PropertyValue>
-  </Record>
-</Annotation>
+
<Annotation Term="UI.RefreshOnChangeOf" PropertyPath="ChangedAt" />
+
+<Annotation Term="Capabilities.UpdateRestrictions">
+  <Record>
+    <PropertyValue Property="NonUpdatableProperties">
+      <Collection>
+        <PropertyPath>CreatedAt</PropertyPath>
+        <PropertyPath>ChangedAt</PropertyPath>
+      </Collection>
+    </PropertyValue>
+  </Record>
+</Annotation>

14.4.1.7 Value Path

The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.

@@ -2470,11 +2471,11 @@

Expression

Example 71:

-
<Annotation Term="org.example.display.DisplayName" Path="FirstName" />
-
-<Annotation Term="org.example.display.DisplayName">
-  <Path>@vCard.Address#work/FullName</Path>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName" Path="FirstName" />
+
+<Annotation Term="org.example.display.DisplayName">
+  <Path>@vCard.Address#work/FullName</Path>
+</Annotation>

14.4.2 Comparison and Logical Operators

Annotations MAY use the following logical and comparison expressions which evaluate to a Boolean value. These expressions MAY be combined and they MAY be used anywhere instead of a Boolean expression.

@@ -2555,52 +2556,52 @@

Example 72:

-
<And>
-  <Path>IsMale</Path>
-  <Path>IsMarried</Path>
-</And>
-<Or>
-  <Path>IsMale</Path>
-  <Path>IsMarried</Path>
-</Or>
-<Not>
-  <Path>IsMale</Path>
-</Not>
-<Eq>
-  <Null />
-  <Path>IsMale</Path>
-</Eq>
-<Ne>
-  <Null />
-  <Path>IsMale</Path>
-</Ne>
-<Gt>
-  <Path>Price</Path>
-  <Int>20</Int>
-</Gt>
-<Ge>
-  <Path>Price</Path>
-  <Int>10</Int>
-</Ge>
-<Lt>
-  <Path>Price</Path>
-  <Int>20</Int>
-</Lt>
-<Le>
-  <Path>Price</Path>
-  <Int>100</Int>
-</Le>
-<Has>
-  <Path>Fabric</Path>
-  <EnumMember>org.example.Pattern/Red</EnumMember>
-</Has>
-<In>
-  <Path>Size</Path>
-  <Collection>
-    <String>XS</String>
-    <String>S</String>
-  </Collection>
-</In>
+
<And>
+  <Path>IsMale</Path>
+  <Path>IsMarried</Path>
+</And>
+<Or>
+  <Path>IsMale</Path>
+  <Path>IsMarried</Path>
+</Or>
+<Not>
+  <Path>IsMale</Path>
+</Not>
+<Eq>
+  <Null />
+  <Path>IsMale</Path>
+</Eq>
+<Ne>
+  <Null />
+  <Path>IsMale</Path>
+</Ne>
+<Gt>
+  <Path>Price</Path>
+  <Int>20</Int>
+</Gt>
+<Ge>
+  <Path>Price</Path>
+  <Int>10</Int>
+</Ge>
+<Lt>
+  <Path>Price</Path>
+  <Int>20</Int>
+</Lt>
+<Le>
+  <Path>Price</Path>
+  <Int>100</Int>
+</Le>
+<Has>
+  <Path>Fabric</Path>
+  <EnumMember>org.example.Pattern/Red</EnumMember>
+</Has>
+<In>
+  <Path>Size</Path>
+  <Collection>
+    <String>XS</String>
+    <String>S</String>
+  </Collection>
+</In>

14.4.3 Arithmetic Operators

Annotations MAY use the following arithmetic expressions which evaluate to a numeric value. These expressions MAY be combined, and they MAY be used anywhere instead of a numeric expression of the appropriate type. The semantics and evaluation rules for each arithmetic expression is identical to the corresponding arithmetic operator defined in OData-URL.

@@ -2653,33 +2654,33 @@

<

Example 73:

-
<Add>
-  <Path>StartDate</Path>
-  <Path>Duration</Path>
-</Add>
-<Sub>
-  <Path>Revenue</Path>
-  <Path>Cost</Path>
-</Sub>
-<Neg>
-  <Path>Height</Path>
-</Neg>
-<Mul>
-  <Path>NetPrice</Path>
-  <Path>TaxRate</Path>
-</Mul>
-<Div>
-  <Path>Quantity</Path>
-  <Path>QuantityPerParcel</Path>
-</Div>
-<DivBy>
-  <Path>Quantity</Path>
-  <Path>QuantityPerParcel</Path>
-</DivBy>
-<Mod>
-  <Path>Quantity</Path>
-  <Path>QuantityPerParcel</Path>
-</Mod>
+
<Add>
+  <Path>StartDate</Path>
+  <Path>Duration</Path>
+</Add>
+<Sub>
+  <Path>Revenue</Path>
+  <Path>Cost</Path>
+</Sub>
+<Neg>
+  <Path>Height</Path>
+</Neg>
+<Mul>
+  <Path>NetPrice</Path>
+  <Path>TaxRate</Path>
+</Mul>
+<Div>
+  <Path>Quantity</Path>
+  <Path>QuantityPerParcel</Path>
+</Div>
+<DivBy>
+  <Path>Quantity</Path>
+  <Path>QuantityPerParcel</Path>
+</DivBy>
+<Mod>
+  <Path>Quantity</Path>
+  <Path>QuantityPerParcel</Path>
+</Mod>

14.4.4 Apply Client-Side Functions

The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function.

@@ -2696,17 +2697,17 @@

OData-ABNF, i.e. Edm.Binary as binaryValue, Edm.Boolean as booleanValue etc.

Example 74:

-
<Annotation Term="org.example.display.DisplayName">
-  <Apply Function="odata.concat">
-    <String>Product: </String>
-    <Path>ProductName</Path>
-    <String> (</String>
-    <Path>Available/Quantity</Path>
-    <String> </String>
-    <Path>Available/Unit</Path>
-    <String> available)</String>
-  </Apply>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName">
+  <Apply Function="odata.concat">
+    <String>Product: </String>
+    <Path>ProductName</Path>
+    <String> (</String>
+    <Path>Available/Quantity</Path>
+    <String> </String>
+    <Path>Available/Unit</Path>
+    <String> available)</String>
+  </Apply>
+</Annotation>

ProductName is of type String, Quantity in complex type Available is of type Decimal, and Unit in Available is of type enumeration, so the result of the Path expression is represented as the member name of the enumeration value.

14.4.4.2 Function odata.fillUriTemplate

@@ -2718,34 +2719,34 @@

labeled element expressions that evaluate to a collection of complex types with two properties that are used in lexicographic order. The first property is used as key, the second property as value.

Example 75: assuming there are no special characters in values of the Name property of the Actor entity

-
<Apply Function="odata.fillUriTemplate">
-  <String>http://host/someAPI/Actors/{actorName}/CV</String>
-  <LabeledElement Name="actorName" Path="Actor/Name" />
-</Apply>
+
<Apply Function="odata.fillUriTemplate">
+  <String>http://host/someAPI/Actors/{actorName}/CV</String>
+  <LabeledElement Name="actorName" Path="Actor/Name" />
+</Apply>

14.4.4.3 Function odata.matchesPattern

The odata.matchesPattern client-side function takes two string expressions as arguments and returns a Boolean value.

The function returns true if the second expression evaluates to an ECMAScript (JavaScript) regular expression and the result of the first argument expression matches that regular expression, using syntax and semantics of ECMAScript regular expressions.

Example 76: all non-empty FirstName values not containing the letters b, c, or d evaluate to true

-
<Apply Function="odata.matchesPattern">
-  <Path>FirstName</Path>
-  <String>^[^b-d]+$</String>
-</Apply>
+
<Apply Function="odata.matchesPattern">
+  <Path>FirstName</Path>
+  <String>^[^b-d]+$</String>
+</Apply>

14.4.4.4 Function odata.uriEncode

The odata.uriEncode client-side function takes one argument of primitive type and returns the URL-encoded OData literal that can be used as a key value in OData URLs or in the query part of OData URLs.

Note: string literals are surrounded by single quotes as required by the paren-style key syntax.

Example 77:

-
<Apply Function="odata.fillUriTemplate">
-  <String>http://host/service/Genres({genreName})</String>
-  <LabeledElement Name="genreName">
-    <Apply Function="odata.uriEncode" >
-      <Path>NameOfMovieGenre</Path>
-    </Apply>
-  </LabeledElement>
-</Apply>
+
<Apply Function="odata.fillUriTemplate">
+  <String>http://host/service/Genres({genreName})</String>
+  <LabeledElement Name="genreName">
+    <Apply Function="odata.uriEncode" >
+      <Path>NameOfMovieGenre</Path>
+    </Apply>
+  </LabeledElement>
+</Apply>

14.4.5 Cast

The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the cast canonical function defined in OData-URL.

@@ -2759,11 +2760,11 @@

Example 78:

-
<Annotation Term="org.example.display.Threshold">
-  <Cast Type="Edm.Decimal">
-    <Path>Average</Path>
-  </Cast>
-</Annotation>
+
<Annotation Term="org.example.display.Threshold">
+  <Cast Type="Edm.Decimal">
+    <Path>Average</Path>
+  </Cast>
+</Annotation>

14.4.6 Collection

The collection expression enables a value to be obtained from zero or more item expressions. The value calculated by the collection expression is the collection of the values calculated by each of the item expressions. The values of the child expressions MUST all be type compatible.

@@ -2773,13 +2774,13 @@

Expre

Example 79:

-
<Annotation Term="org.example.seo.SeoTerms">
-  <Collection>
-    <String>Product</String>
-    <String>Supplier</String>
-    <String>Customer</String>
-  </Collection>
-</Annotation>
+
<Annotation Term="org.example.seo.SeoTerms">
+  <Collection>
+    <String>Product</String>
+    <String>Supplier</String>
+    <String>Customer</String>
+  </Collection>
+</Annotation>

14.4.7 If-Then-Else

The if-then-else expression enables a value to be obtained by evaluating a condition expression. It MUST contain exactly three child expressions. There is one exception to this rule: if and only if the if-then-else expression is an item of a collection expression, the third child expression MAY be omitted, reducing it to an if-then expression. This can be used to conditionally add an element to a collection.

@@ -2793,13 +2794,13 @@

Expression edm:

Example 80: the condition is a value path expression referencing the Boolean property IsFemale, whose value then determines the value of the edm:If expression (or so it was long ago)

-
<Annotation Term="org.example.person.Gender">
-  <If>
-    <Path>IsFemale</Path>
-    <String>Female</String>
-    <String>Male</String>
-  </If>
-</Annotation>
+
<Annotation Term="org.example.person.Gender">
+  <If>
+    <Path>IsFemale</Path>
+    <String>Female</String>
+    <String>Male</String>
+  </If>
+</Annotation>

14.4.8 Is-Of

The is-of expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true if the child expression returns a type that is compatible with the specified type, and false otherwise.

@@ -2811,11 +2812,11 @@

Expression

Example 81:

-
<Annotation Term="self.IsPreferredCustomer">
-  <IsOf Type="self.PreferredCustomer">
-    <Path>Customer</Path>
-  </IsOf>
-</Annotation>
+
<Annotation Term="self.IsPreferredCustomer">
+  <IsOf Type="self.PreferredCustomer">
+    <Path>Customer</Path>
+  </IsOf>
+</Annotation>

14.4.9 Labeled Element

The labeled element expression assigns a name to its single child expression. The value of the child expression can then be reused elsewhere with a labeled element reference expression.

@@ -2831,15 +2832,15 @@

Example 82:

-
<Annotation Term="org.example.display.DisplayName">
-  <LabeledElement Name="CustomerFirstName" Path="FirstName" />
-</Annotation>
-
-<Annotation Term="org.example.display.DisplayName">
-  <LabeledElement Name="CustomerFirstName">
-    <Path>FirstName</Path>
-  </LabeledElement>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName">
+  <LabeledElement Name="CustomerFirstName" Path="FirstName" />
+</Annotation>
+
+<Annotation Term="org.example.display.DisplayName">
+  <LabeledElement Name="CustomerFirstName">
+    <Path>FirstName</Path>
+  </LabeledElement>
+</Annotation>

14.4.10 Labeled Element Reference

The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value.

@@ -2849,9 +2850,9 @@

Example 83:

-
<Annotation Term="org.example.display.DisplayName">
-  <LabeledElementReference>Model.CustomerFirstName</LabeledElementReference>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName">
+  <LabeledElementReference>Model.CustomerFirstName</LabeledElementReference>
+</Annotation>

14.4.11 Null

The null expression indicates the absence of a value. The null expression MAY be annotated.

@@ -2861,17 +2862,17 @@

Expression

Example 84:

-
<Annotation Term="org.example.display.DisplayName">
-  <Null/>
-</Annotation>
+
<Annotation Term="org.example.display.DisplayName">
+  <Null/>
+</Annotation>

Example 85:

-
<Annotation Term="@UI.Address">
-  <Null>
-    <Annotation Term="self.Reason" String="Private" />
-  </Null>
-</Annotation>
+
<Annotation Term="@UI.Address">
+  <Null>
+    <Annotation Term="self.Reason" String="Private" />
+  </Null>
+</Annotation>

14.4.12 Record

The record expression enables a new entity type or complex type instance to be constructed.

@@ -2924,24 +2925,24 @@

Expression

Example 87:

-
<Annotation Term="org.example.person.Supplier">
-  <UrlRef>
-    <Apply Function="odata.fillUriTemplate">
-      <String>http://host/service/Suppliers({suppID})</String>
-      <LabeledElement Name="suppID">
-      <Apply Function="odata.uriEncode">
-        <Path>SupplierId</Path>
-      </Apply>
-      </LabeledElement>
-     </Apply>
-  </UrlRef>
-</Annotation>
-
-<Annotation Term="Core.LongDescription">
-  <UrlRef><String>http://host/wiki/HowToUse</String></UrlRef>
-</Annotation>
-
-<Annotation Term="Core.LongDescription" UrlRef="http://host/wiki/HowToUse" />
+
<Annotation Term="org.example.person.Supplier">
+  <UrlRef>
+    <Apply Function="odata.fillUriTemplate">
+      <String>http://host/service/Suppliers({suppID})</String>
+      <LabeledElement Name="suppID">
+      <Apply Function="odata.uriEncode">
+        <Path>SupplierId</Path>
+      </Apply>
+      </LabeledElement>
+     </Apply>
+  </UrlRef>
+</Annotation>
+
+<Annotation Term="Core.LongDescription">
+  <UrlRef><String>http://host/wiki/HowToUse</String></UrlRef>
+</Annotation>
+
+<Annotation Term="Core.LongDescription" UrlRef="http://host/wiki/HowToUse" />

15 Identifier and Path Values

@@ -2979,114 +2980,114 @@

16 CSDL Ex

16.1 Products and Categories Example

Example 89:

-
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
-           xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
-  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
-    <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
-      <Annotation Term="Core.DefaultNamespace" />
-    </edmx:Include>
-  </edmx:Reference>
-  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
-    <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
-  </edmx:Reference>
-  <edmx:DataServices>
-    <Schema Namespace="ODataDemo">
-      <EntityType Name="Product" HasStream="true">
-        <Key>
-          <PropertyRef Name="ID" />
-        </Key>
-        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="Description" Type="Edm.String" >
-          <Annotation Term="Core.IsLanguageDependent" />
-        </Property>
-        <Property Name="ReleaseDate" Type="Edm.Date" />
-        <Property Name="DiscontinuedDate" Type="Edm.Date" />
-        <Property Name="Rating" Type="Edm.Int32" />
-        <Property Name="Price" Type="Edm.Decimal" Scale="variable">
-          <Annotation Term="Measures.ISOCurrency" Path="Currency" />
-        </Property>
-        <Property Name="Currency" Type="Edm.String" MaxLength="3" />
-        <NavigationProperty Name="Category" Type="ODataDemo.Category"
-                            Nullable="false" Partner="Products" />
-        <NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
-                            Partner="Products" />
-      </EntityType>
-      <EntityType Name="Category">
-        <Key>
-         <PropertyRef Name="ID" />
-        </Key>
-        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
-        <Property Name="Name" Type="Edm.String" Nullable="false">
-          <Annotation Term="Core.IsLanguageDependent" />
-        </Property>
-        <NavigationProperty Name="Products" Partner="Category"
-                            Type="Collection(ODataDemo.Product)">
-          <OnDelete Action="Cascade" />
-        </NavigationProperty>
-      </EntityType>
-      <EntityType Name="Supplier">
-        <Key>
-          <PropertyRef Name="ID" />
-        </Key>
-        <Property Name="ID" Type="Edm.String" Nullable="false" />
-        <Property Name="Name" Type="Edm.String" />
-        <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
-        <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
-        <NavigationProperty Name="Products" Partner="Supplier"
-                            Type="Collection(ODataDemo.Product)" />
-      </EntityType>
-      <EntityType Name="Country">
-        <Key>
-          <PropertyRef Name="Code" />
-        </Key>
-        <Property Name="Code" Type="Edm.String" MaxLength="2"
-                              Nullable="false" />
-        <Property Name="Name" Type="Edm.String" />
-      </EntityType>
-      <ComplexType Name="Address">
-        <Property Name="Street" Type="Edm.String" />
-        <Property Name="City" Type="Edm.String" />
-        <Property Name="State" Type="Edm.String" />
-        <Property Name="ZipCode" Type="Edm.String" />
-        <Property Name="CountryName" Type="Edm.String" />
-        <NavigationProperty Name="Country" Type="ODataDemo.Country">
-          <ReferentialConstraint Property="CountryName"  
-                                 ReferencedProperty="Name" />
-        </NavigationProperty>
-      </ComplexType>
-      <Function Name="ProductsByRating">
-        <Parameter Name="Rating" Type="Edm.Int32" />
-        <ReturnType Type="Collection(ODataDemo.Product)" />
-      </Function>
-      <EntityContainer Name="DemoService">
-        <EntitySet Name="Products" EntityType="ODataDemo.Product">
-          <NavigationPropertyBinding Path="Category" Target="Categories" />
-        </EntitySet>
-        <EntitySet Name="Categories" EntityType="ODataDemo.Category">
-          <NavigationPropertyBinding Path="Products" Target="Products" />
-          <Annotation Term="Core.Description" String="Product Categories" />
-        </EntitySet>
-        <EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
-          <NavigationPropertyBinding Path="Products" Target="Products" />
-          <NavigationPropertyBinding Path="Address/Country"
-                                     Target="Countries" />
-          <Annotation Term="Core.OptimisticConcurrency">
-            <Collection>
-              <PropertyPath>Concurrency</PropertyPath>
-            </Collection>
-          </Annotation>
-        </EntitySet>
-        <Singleton Name="MainSupplier" Type="self.Supplier">
-          <NavigationPropertyBinding Path="Products" Target="Products" />
-          <Annotation Term="Core.Description" String="Primary Supplier" />
-        </Singleton>
-        <EntitySet Name="Countries" EntityType="ODataDemo.Country" />
-        <FunctionImport Name="ProductsByRating" EntitySet="Products"
-                        Function="ODataDemo.ProductsByRating" />
-      </EntityContainer>
-    </Schema>
-  </edmx:DataServices>
-</edmx:Edmx>
+
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
+           xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
+  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
+    <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
+      <Annotation Term="Core.DefaultNamespace" />
+    </edmx:Include>
+  </edmx:Reference>
+  <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
+    <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
+  </edmx:Reference>
+  <edmx:DataServices>
+    <Schema Namespace="ODataDemo">
+      <EntityType Name="Product" HasStream="true">
+        <Key>
+          <PropertyRef Name="ID" />
+        </Key>
+        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Description" Type="Edm.String" >
+          <Annotation Term="Core.IsLanguageDependent" />
+        </Property>
+        <Property Name="ReleaseDate" Type="Edm.Date" />
+        <Property Name="DiscontinuedDate" Type="Edm.Date" />
+        <Property Name="Rating" Type="Edm.Int32" />
+        <Property Name="Price" Type="Edm.Decimal" Scale="variable">
+          <Annotation Term="Measures.ISOCurrency" Path="Currency" />
+        </Property>
+        <Property Name="Currency" Type="Edm.String" MaxLength="3" />
+        <NavigationProperty Name="Category" Type="ODataDemo.Category"
+                            Nullable="false" Partner="Products" />
+        <NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
+                            Partner="Products" />
+      </EntityType>
+      <EntityType Name="Category">
+        <Key>
+         <PropertyRef Name="ID" />
+        </Key>
+        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" Nullable="false">
+          <Annotation Term="Core.IsLanguageDependent" />
+        </Property>
+        <NavigationProperty Name="Products" Partner="Category"
+                            Type="Collection(ODataDemo.Product)">
+          <OnDelete Action="Cascade" />
+        </NavigationProperty>
+      </EntityType>
+      <EntityType Name="Supplier">
+        <Key>
+          <PropertyRef Name="ID" />
+        </Key>
+        <Property Name="ID" Type="Edm.String" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" />
+        <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
+        <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
+        <NavigationProperty Name="Products" Partner="Supplier"
+                            Type="Collection(ODataDemo.Product)" />
+      </EntityType>
+      <EntityType Name="Country">
+        <Key>
+          <PropertyRef Name="Code" />
+        </Key>
+        <Property Name="Code" Type="Edm.String" MaxLength="2"
+                              Nullable="false" />
+        <Property Name="Name" Type="Edm.String" />
+      </EntityType>
+      <ComplexType Name="Address">
+        <Property Name="Street" Type="Edm.String" />
+        <Property Name="City" Type="Edm.String" />
+        <Property Name="State" Type="Edm.String" />
+        <Property Name="ZipCode" Type="Edm.String" />
+        <Property Name="CountryName" Type="Edm.String" />
+        <NavigationProperty Name="Country" Type="ODataDemo.Country">
+          <ReferentialConstraint Property="CountryName"  
+                                 ReferencedProperty="Name" />
+        </NavigationProperty>
+      </ComplexType>
+      <Function Name="ProductsByRating">
+        <Parameter Name="Rating" Type="Edm.Int32" />
+        <ReturnType Type="Collection(ODataDemo.Product)" />
+      </Function>
+      <EntityContainer Name="DemoService">
+        <EntitySet Name="Products" EntityType="ODataDemo.Product">
+          <NavigationPropertyBinding Path="Category" Target="Categories" />
+        </EntitySet>
+        <EntitySet Name="Categories" EntityType="ODataDemo.Category">
+          <NavigationPropertyBinding Path="Products" Target="Products" />
+          <Annotation Term="Core.Description" String="Product Categories" />
+        </EntitySet>
+        <EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
+          <NavigationPropertyBinding Path="Products" Target="Products" />
+          <NavigationPropertyBinding Path="Address/Country"
+                                     Target="Countries" />
+          <Annotation Term="Core.OptimisticConcurrency">
+            <Collection>
+              <PropertyPath>Concurrency</PropertyPath>
+            </Collection>
+          </Annotation>
+        </EntitySet>
+        <Singleton Name="MainSupplier" Type="self.Supplier">
+          <NavigationPropertyBinding Path="Products" Target="Products" />
+          <Annotation Term="Core.Description" String="Primary Supplier" />
+        </Singleton>
+        <EntitySet Name="Countries" EntityType="ODataDemo.Country" />
+        <FunctionImport Name="ProductsByRating" EntitySet="Products"
+                        Function="ODataDemo.ProductsByRating" />
+      </EntityContainer>
+    </Schema>
+  </edmx:DataServices>
+</edmx:Edmx>

16.2 Annotations for Products and Categories Example

diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md index b487c86ae..e9a9b33f1 100644 --- a/docs/odata-csdl-xml/odata-csdl-xml.md +++ b/docs/odata-csdl-xml/odata-csdl-xml.md @@ -4234,8 +4234,13 @@ segment](#TermCast). ::: example Example 64: model path addressing an annotation on a navigation property +vs. term cast addressing an annotation on the resource addressed by the navigation property ``` -.../Items@Capabilities.InsertRestrictions/Insertable +.../Items@Core.Description +``` + +``` +.../Items/@Core.Description ``` ::: diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md index 0cedcd963..fa5fde350 100644 --- a/odata-csdl/14 Vocabulary and Annotation.md +++ b/odata-csdl/14 Vocabulary and Annotation.md @@ -1320,8 +1320,13 @@ segment](#TermCast). ::: example Example ##ex: model path addressing an annotation on a navigation property +vs. term cast addressing an annotation on the resource addressed by the navigation property ``` -.../Items@Capabilities.InsertRestrictions/Insertable +.../Items@Core.Description +``` + +``` +.../Items/@Core.Description ``` :::