General

Services, Interfaces and Interface Operations

This document uses the Industrie 4.0 Service Model illustrated in Figure 1 for a uniform understanding and naming. It basically distinguishes between associated concepts on several levels (from left to right):

  • technology-neutral level: concepts that are independent of selected technologies;

  • technology-specific level: concepts that are instantiated for a given technology and/or architectural style (e.g. HTTP/REST, OPC UA, MQTT);

  • implementation level: concepts that are related to an implementation architecture that comprises one or more technologies (e.g. C#, C++, Java, Python);

  • runtime level: concepts that are related to identifiable components in an operational Industry 4.0 system.

This document deals with the concepts of the technology-neutral and technology-specific level. However, to avoid terminological and conceptual misunderstandings, the whole Industrie 4.0 Service Model is provided here.

The technology-neutral level comprises the following concepts:

  • Service: a service describes a demarcated scope of functionality (including its informational and non-functional aspects), which is offered by an entity or organization via interfaces.

  • Interface: this is the most important concept as it is understood to be the unit of reusability across services and the unit of standardization when mapped to application programming interfaces (API) in the technology-specific level. One interface may be mapped to several APIs depending on the technology and architectural style used, e.g. HTTP/REST or OPC UA, whereby these API mappings also need to be standardized for the sake of interoperability.

  • Interface-Operation: interface operations define interaction patterns via the specified interface.

The technology-specific level comprises the following concepts:

  • Service Specification: specification of a service according to the notation, architectural style, and constraints of a selected technology. Among others, it comprises and refers to the list of APIs that forms this service specification. These may be I4.0-defined standard APIs but also other, proprietary APIs.

Note: such a technology-specific service specification may be but does not have to be derived from the “service” described in the technology-neutral form. It is up to the system architect and service engineer to tailor the technology-specific service according to the needs of the use cases.

  • API: specification of the set of operations and events that forms an API in a selected technology. It is derived from the interface description on the technology-neutral level. Hence, if there are several selected technologies, one interface may be mapped to several APIs.

  • API-Operation: specification of a single operation (procedure) that may be called through an API. It is derived from the interface operation description on the technology-neutral level. When selecting technologies, one interface operation may be mapped to several API-operations; several interface operations may also be mapped to the same API-operation.

The implementation level comprises the following concepts:

  • Service-Implementation: service realized in a selected implementation language following the specification in the Service Specification description on the technology-specific level.

  • API-Implementation: set of operations realized in a selected implementation language following the specification in the API description on the technology-specific level.

  • API-Operation-Implementation: concrete realization of an operation in a selected implementation language following the specification in the API-Operation description on the technology-specific level.

The runtime level comprises the following concepts:

  • Service-Instance: instance of a Service-Implementation including its API-Instances for communication. Additionally, it has an identifier to be identifiable within a given context.

  • API-Instance: instance of an API-Implementation which has an endpoint to get the information about this instance and the related operations.

  • API-Operation-Instance: instance of an API-Operation-Implementation which has an endpoint to get invoked.

Services, Interfaces & APIs and Operations
Figure 1. Services, Interfaces & APIs and Operations

One important message from the Industrie 4.0 Service Model is that it is the level of the interface (mapped to technology-specific APIs) that

  • provides the unit of reusability,

  • is the foundation for interoperable services, and

  • provides the reference unit for compliance statements.

Therefore, this document defines the interfaces and operations which are needed for interaction regarding the elements of the Asset Administration Shell metamodel starting with Clause Asset Administration Shell Interfaces.

Design Principles

The operations of the interfaces follow a resource-oriented approach which is close to general REST principles but not as strict in every situation. The approach consists of the three main agreements:

  • Stateless: the API is stateless. Each operation is independent. The server is always consistent after each operation.

  • Resources (nouns): each resource is a clearly defined noun. This means that it has a specific name and its relation to other nouns is defined. The nouns and the relationships between them are taken from the list of referable objects of “Specification of the Asset Administration Shell Part 1” and their relationships. Metamodel Specification Details gives an additional list of resources.

  • Methods (verbs): a small set of standard REST methods (GET, POST, PUT, DELETE) is used to describe the semantic of the most common operations. There are only a few exceptions for situations where the standard methods do not fit (e.g. GETALL, SET, INVOKE).

The methods are:

  • GET: a GET returns a single resource based on the resource identifier which is the identifier [1] for identifiables and the idShortPath for referables.

  • GETALL: returns a list of resources based on optionally available parameters such as filters.

  • QUERY: returns a list of resources based on conditions expressed through the AAS Query Language.

  • PUT: replaces an existing resource.

  • PUTBULK: bulk replacement.

  • POST: creates a new resource. The identifier of the resource is part of the resource description. This is necessary because the id of identifiables is globally unique and should be the identifier for the object in every system. This implies that the creation of an identifiable is idempotent. There shall never be more than one identifiable with the same ID in one system. For example, trying to post the same AAS object twice will not create two AAS resources.

  • POSTBULK: bulk creation.

  • PATCH: updates an existing resource. The content to be replaced will be defined by the given SerializationModifiers, e.g. content=value provides the ValueOnly-serialization to update all values in the existing resource. The structure of the existing resource on the server and of the content given by the PATCH must be the same.

Note 1: values remain unchanged with content=metadata.

  • DELETE: deletes a resource based on a given identifier.

  • DELETEBULK: bulk deletion.

  • INVOKE: invokes an operation at a specified path.

  • INVOKEASYNC: asyncronous invocation of an operation.

  • SEARCHALL: returns a list fo resources based on asset links.

Note 2: these methods are intended for the naming of interfaces as described in Figure 1. They shall not be interpreted as new protocol methods, e.g. on HTTP level.

Naming rules for operations:

The following rules shall apply for the operation names in Asset Administration Shell Interface, Submodel Interface, Shell Repository Interface, Submodel Repository Interface, Concept Description Repository Interface:

<Interface Operation> ::= <Method Verb><Model Element Name>[<Modifier>]["By"<By-Qualifier>]

<Method Verb> ::= "Get" | "GetAll" | "Query" |"Put" | "PutBulk" | "Post" | "PostBulk" | "Patch" | "Delete" | "DeleteBulk" | "Invoke" | "InvokeAsync" | "SearchAll"

<Model Element Name> ::= "AssetAdministrationShell"["Ids"|"s"] | "AssetAdministrationShellDescriptor"["Ids"|"s"] | "SubmodelReference"["s"] | "AssetInformation" | "Submodel"["Ids"|"s"] | "SubmodelDescriptor"["Ids"|"s"] | "SubmodelElement"["s"] | "ConceptDescription"["Ids"|"s"]

<Modifier> ::= "Value" | "IdShortPath" | "Reference"

<By-Qualifier> ::= | "Id" | "SemanticId" | "ParentPathAndSemanticId" | "Path" | "AssetId" | "IdShort" | "IsCaseOf" | "DataSpecificationReference"

Examples:

GetSubmodel has method verb “Get” and model element name “Submodel”.

GetAllSubmodelElementsByPath has method verb “GetAll” and model element name “SubmodelElements” plus a by-qualifier “Path”.

Semantic References for Operations

The operations of this document need unique identifiers to reach a common understanding and allow all involved parties to reference the same things. These identifiers need to be globally unique and understandable by the community and implementing systems. Furthermore, the identifiers need to support a versioning scheme for future updates and extensions of the metamodel. The identifiers defined in this document are reused in related resources, for instance REST API operations or in self-descriptions of implementing services.

Internationalized Resource Identifiers (IRIs), Uniform Resource Identifiers (URIs) [5] in particular, and the requirements of DIN SPEC 91406 [6], serve as the basic format. Further design decisions include ‘https’ as the URI scheme, and the controlled domain name ‘admin-shell.io’ as the chosen authority. Both decisions guarantee the interoperability of the identifiers and their durability, since URIs are generally well-known and proven, while the domain is controlled and served through the Industrial Digital Twin Association (IDTA). All identifiers included in the ‘admin-shell.io’ domain are described in a lightweight catalogue in the form of Markdown documents; they are continuously maintained and updated https://github.com/admin-shell-io/id. The catalogue itself is structured in several sub-namespaces specified by the first path parameter. All URIs of this document reflect entities of the core metamodel, which are contained in the sub-namespace identified with the ‘/aas/API’ path.

The described identifiers appear mainly in the semanticId field of every class and operation. They are required since the class name is not necessarily constant over time. The respective semanticIds, however, guarantee the unique and certain relation between a reference and the referenced class or operation. The URIs are constructed as follows (compare to Clause Semantic Identifiers for Metamodel and Data Specifications in Part 1 [1]).

Note 1: version information is explicitly included in each identifier.

Note 2: even though the usage of the ‘https’ scheme might indicate URLs, all identifiers are regarded as URI look-ups; dereferencing them cannot be expected.

The following grammar is used to create valid identifiers:

<Identifier> ::= <Namespace>"/aas/API/"<OperationName>"/"<Version>

<Namespace> ::= "https://admin-shell.io

<OperationName> ::= {<Character>}+

<Version> ::= {<Digit>}+"/"{<Digit>}+["/"{<Character>}+]

<Digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

<Character> ::= an unreserved character permitted by DIN SPEC 91406

? ::= zero or one

+ ::= one or more

Examples for valid identifiers:

  • https://admin-shell.io/aas/API/GetSubmodel/1/23

  • https://admin-shell.io/aas/API/GetAllSubmodelElements/1/0/RC03

  • https://admin-shell.io/aas/API/GetAllSubmodelElements/3/0

Examples for invalid identifiers:

  • http://admin-shell.io/API/GetSubmodel/1/0
    The scheme is different to ‘https’, and the ‘aas’ path segment is missing

  • https://admin-shell.io/aas/API/GetSubmodel
    Version information is missing

  • https://admin-shell.io/aas/API/GetSubmodel/1/0#0173-%20ABC#001
    The URI includes DIN SPEC 91406-reserved (#) and impermissible (%) characters

References and Keys

The concept of references is introduced in Part 1 of the series “Specification of the Asset Administration Shell” [1].

When defining interfaces, a distinction is made between relative references and absolute references.

Absolute references require a global unique id as starting point of the reference to be resolvable. In this case the type “Reference” is used.

Relative references do not start with a global unique id. Instead, it is assumed that the context is given and unique. In this case, the key list only contains keys with Key/type that references a non-identifiable referable (e.g. a Property, a Range, a RelationshipElement, etc.).

Relation of Interfaces

The following chapters define several interfaces, which work together as a system and support different deployment scenarios.

There are three major components of the overall system:

  1. Repositories store the data of Asset Administration Shells, Submodels, and Concept Descriptions,

  2. Registries are “directories” which store AAS-IDs and Submodel-IDs together with the related endpoints (typically a URL-path into a repository or to a single AAS/Submodel),

  3. discovery (servers) supports a fast search and only store copies of essential information, i.e. key value pairs to find IDs by other IDs.

Figure 2 shows a typical sequence. Discovery finds the AAS-ID for a given Asset-ID. A Registry provides the endpoint for a given AAS-ID. Such an endpoint for an AAS and the related Submodel-IDs make the submodels with their submodelElements accessible.

The Asset Administration Shell model is an asset-oriented model.

An Asset-ID may be retrieved e.g. by a QRCODE on the asset, by an RFID for the asset, from the firmware of the asset or from an asset database. IEC 61406 (formerly DIN SPEC 91406) defines the format of such Asset-IDs.

The “Administration Shell Basic Discovery Interface” may be used with an Asset-ID to get the related AAS-IDs (“GetAllAssetAdministrationShellIdsByAssetLink”).

The “Asset Administration Shell Registry Interface” may be used with an AAS-ID to retrieve the related descriptor for an AAS (“GetAssetAdministrationShellDescriptorById”). The retrieved AAS Descriptor includes the endpoint for the “Asset Administration Shell Interface”.

The “Asset Administration Shell Interface” makes the information about the AAS itself and the references to the related submodels available.

The related submodels of an AAS are retrieved by “GetAllSubmodelReferences”. Such a reference includes the SM-ID of a related submodel.

Similarly to the AAS above, the “Submodel Registry Interface” may be used to retrieve the related descriptor for a submodel (“GetSubmodelDescriptorById”) with a specific SM-ID. The retrieved Submodel Descriptor includes the endpoint for the “Submodel Interface”.

The “Submodel Interface” makes the information about the submodel itself and all its included submodel elements available.

Asset Administration Shells and submodels may be deployed on different endpoints in different ways.

One example is the deployment of an AAS on a device. In this case, the AAS might be fixed and might not be changed or deleted. In a cloud scenario, a single AAS may also be deployed as a single container (e.g. docker container).

Another example is the deployment of many Asset Administration Shells in an AAS Repository. In this case, the “Asset Administration Shell Repository Interface” may allow to create and manage multiple AAS in the repository.

The separate interfaces of the HTTP/REST API allow many ways to support different deployments.

For an AAS repository, the combination “Asset Administration Shell Repository Interface”, “Asset Administration Shell Interface”, “Submodel Interface”, “Serialization Interface”, and “Self-Description Interface” is proposed.

This will result in the following HTTP/REST paths as described in a combined OpenAPI file AssetAdministrationShellRepositoryServiceSpecification/V3.1_SSP-001.[1]:

/shells
/shells/{aas-identifier}
/shells/{aas-identifier}/asset-information
/shells/{aas-identifier}/asset-information/thumbnail
/shells/{aas-identifier}/submodel-refs
/shells/{aas-identifier}/submodel-refs/{submodel-identifier}
/shells/{aas-identifier}/submodels/{submodel-identifier}
/shells/{aas-identifier}/submodels/{submodel-identifier}/submodel-elements
/shells/{aas-identifier}/submodels/{submodel-identifier}/submodel-elements/{idShortPath}
/shells/{aas-identifier}/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/attachment
/shells/{aas-identifier}/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/invoke
/shells/{aas-identifier}/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/invoke-async
/shells/{aas-identifier}/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/operation-status/{handleId}
/shells/{aas-identifier}/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/operation-results/{handleId}
/serialization
/description

If the repository also supports AASX Packages, it shall be extended by additionally supporting a “AASX File Server” Profile [Related OpenAPI file: https://app.swaggerhub.com/apis/Plattform_i40/AasxFileServerServiceSpecification/V3.1_SSP-001].

The example of a device or container containing one AAS with its related submodels will result in the following HTTP/REST paths as described in the related OpenAPI file AssetAdministrationShellServiceSpecification/V3.1_SSP-001footnote:[Related OpenAPI file: AasxFileServerServiceSpecification/V3.0_SSP-001:

/aas
/aas/asset-information
/aas/asset-information/thumbnail
/aas/submodel-refs
/aas/submodel-refs/{submodel-identifier}
/aas/submodels/{submodel-identifier}
/aas/submodels/{submodel-identifier}/submodel-elements
/aas/submodels/{submodel-identifier}/submodel-elements/{idShortPath}
/aas/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/attachment
/aas/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/invoke
/aas/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/invoke-async
/aas/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/operation-status/{handleId}
/aas/submodels/{submodel-identifier}/submodel-elements/{idShortPath}/operation-results/{handleId}
/serialization
/description

Note: identifiers are base64url-encoded in the API, i.e. {aas-identifier} and {submodel-identifier}. The {idShortPath} is URL-encoded in the API.

Query Language

Many use cases of the Asset Administration Shell require the involvement of a high number of Asset Administration Shells at the same time. Executing the business logic on all potentially involved Asset Administration Shells solely by the client application requires a huge amount of transferred data objects and bandwidth. It is therefore necessary to send parts of the selection conditions to the AAS hosting systems. The AAS Query Language enables AAS clients to describe and handover their interests and AAS servers to only respond with the needed data objects.

The Asset Administration Shell propagates a Query Language inspired by the so-called Resource Query Language (RQL [11]). This language follows a simplified grammar and expressiveness compared with RQL and other languages with a similar scope, e.g. SPARQL [12], GQL [13], or JsonPath [14]. The same language shall be used independent of the communication protocol, therefore, it is not limited to the HTTP API of the AAS. However, different communication protocols may treat aspects differently, e.g., by requiring different query or result set serialisations, variations in the order of constructs, or endpoint patterns. Nevertheless, all share the same expressiveness, and under same conditions a query shall lead to the same results independently of the chosen communication protocol.

Note: The AAS Query Language and the AAS Access Rules [3] share the same BNF grammar. Therefore, the result is a superset, with query as the entrypoint for the Query Language.

Use Case Examples

Examples for Use Cases are search queries in the submodels DigitalNameplate, TechnicalData or HandoverDocumentation.
DigitalNameplate has a fixed structure, only the bottom part with Markings and AssetSpecificProperties is variable. Queries in DigitalNameplate can be well done by providing idShortPaths to the elements in the query, e.g. searching for all DigitalNameplates with a certain ManufacturerName and CountryOfOrigin.
TechnicalData has its major variable part on the bottom and a small fixed structure on the top. TechnicalData includes ProductClassifications with ProductClassId, so that e.g. by ECLASS ClassId a certain product type can be queried. TechnicalData includes all the technical properties, e.g. width of the product. An example is to search for motor starters (ProductClassifications.ProductClassificationItem.ProductClassId = 27-37-09-05) with a width less than 100 mm (semanticId = 0173-1#02-BAF016#006, value < 100). HandoverDocumentation consists basically of a list of document information according VDI 2770 (DocumentedEntity{00}). It is expected, that this will be changed to SubmodelElementList like other V3 Submodels. An example is to search for Documents of a certain ClassId (semanticId = 0173-1#02-ABH996#001, ClassId = "03-01", i.e. Commissioning) in a certain language (semanticId = 0173-1#02-AAN468#006, e.g. value = "nl").

Main elements of the AAS Query Language
Figure 3. Main elements of the AAS Query Language

Limitations

The AAS Query Language is not intended as feature-comparable to existing query languages like SPARQL or GQL. In case the expressiveness of such technologies is needed, a software vendor might additionally extend his service accordingly. However, in order to keep the additional overhead for AAS Query Language implementers as small as possible, the following limitations apply:

  1. The AAS Query Language focusses on Identifiables: It is only possible to formulate queries for Asset Administration Shells, Submodels, and their according Descriptors, as well as ConceptDescription objects. In addition, also their identifiers (values of the "id" attributes) can be queried. This means in particular that not every Referable can be queried.

  2. Only Repository and Registry Services have specified query functionalities: Querys on Asset Administration Shell Services or Submodel Services are not defined.

  3. Only selected attributes defined by the AAS data model [1] can be used as conditions for returned objects: Usage of custom or vendor-specific attributes outside of the AAS specifications is generally not recommended and may lead to a rejections of the query by the receiving systems.

  4. It is not possible to traverse through the specific fields of the SubmodelElements Entity (e.g. Entity/statements), AnnotatedRelationshipElement (e.g. AnnotatedRelationshipElement/annotations), or Operation (e.g. Operation/outputVariables). Only the fields semanticId idShort, value, and valueType are available for SubmodelElements.

Search in AAS Hierarchy

AAS consists of a hierarchical structure. An AAS references its "contained" submodels. A submodel contains a list of SubmodelElements, which may include further SubmodelElements, and so on. The query language allows to both address a specific instance of the data or to search all data in a repository. A specific instance is addressed by specifying the id of an Identifiable and the idShortPath to a Referable in a Submodel. If such explicit information is not specified, a hierarchical search is made. By the $aas FieldIdentifier conditions for all the relevant AAS are defined. By the $sm FieldIdentifier conditions for all the relevant submodels are defined. $sm can be used with and without $aas. If $aas and $sm are used together, only the submodels referenced by the matching $aas are searched by the $sm expression. The same search principle is used, when combining $sm and $sme. In such case only the SubmodelElements which are part of matching submodels by $sm expression are searched by the $sme expression. Several such hierarchical conditions may even be combined by $match expressions.

Grammar

The content and structure of the AAS Query Language is defined in the context-free Backus-Naur form (BNF). See Appendix Backus-Naur-Form for more details on BNF. The detailed serialisation and interaction patterns are defined by the different technology mappings, e.g., the AAS HTTP API represents AAS Queries as JSON objects (see Clause Serialisation). Other mappings may define different serialisations, however, all have to follow the general structure of queries defined in the following grammar.

This is the combined grammar for the AAS Query Language and the AAS Access Rules defined by the AAS Security specification [3].

<grammar> ::= <query> | <AllAccessPermissionRules>

<query> ::= <selectStatement>? <logicalExpression>
<selectStatement> ::= "$select" <ws> "id" <ws>

<logicalExpression> ::= <logicalNestedExpression> | <logicalOrExpression> | <logicalAndExpression> |
<logicalNotExpression> | <matchExpression> | <BoolLiteral> | <castToBool> | <singleComparison>
<logicalNestedExpression> ::= "(" <ws> <logicalExpression> ")" <ws>
<logicalOrExpression> ::= "$or" <ws> "(" <ws> <logicalExpression> ( "," <ws> <logicalExpression> )+ ")" <ws>
<logicalAndExpression> ::= "$and" <ws> "(" <ws> <logicalExpression> ( "," <ws> <logicalExpression> )+ ")" <ws>
<logicalNotExpression> ::= "$not" <ws> "(" <ws> <logicalExpression> ")" <ws>

<matchExpression> ::= ( "$match" <ws> "(" <ws> ( <singleComparison> | <matchExpression> ) ( "," <ws> ( <singleComparison> | <matchExpression> ) )* ")" <ws> )

<singleComparison> ::=
    <stringComparison> |
    <numericalComparison> |
    <hexComparison> |
    <boolComparison> |
    <dateTimeComparison> |
    <timeComparison>

<allComparisons> ::= ( "$eq" | "$ne" | "$gt" | "$lt" | "$ge" | "$le" )

<stringComparison> ::=
    ( ( "$starts-with" | "ends-with" | "$contains" | "$regex") <ws> "(" <ws> <stringOperand> <ws> "," <ws> <stringOperand> <ws> ")" <ws> ) |
    ( <stringOperand> <ws> <allComparisons> <ws> <stringOperand> <ws> ) |
    ( <stringOperand> <ws> <allComparisons> <ws> <FieldIdentifierString> <ws> ) |
    ( <FieldIdentifierString> <ws> <allComparisons> <ws> <stringOperand> <ws> )

<numericalComparison> ::=
    ( <numericalOperand> <ws> <allComparisons> <ws> <numericalOperand> <ws> ) |
    ( <numericalOperand> <ws> <allComparisons> <ws> <FieldIdentifierString> <ws> ) |
    ( <FieldIdentifierString> <ws> <allComparisons> <ws> <numericalOperand> <ws> )

<hexComparison> ::=
    <hexOperand> <ws> <allComparisons> <ws> <hexOperand> <ws>

<boolComparison> ::=
    <boolOperand> <ws> ( "$eq" | "$ne" ) <ws> <boolOperand> <ws>

<dateTimeComparison> ::=
    <dateTimeOperand> <ws> <allComparisons> <ws> <dateTimeOperand> <ws>

<dateTimeToNum> ::=
    ( "$dayOfWeek" | "$dayOfMonth" | "$month" | "$year" ) <ws> "(" <ws> <dateTimeOperand> <ws> ")" <ws>

<timeComparison> ::=
    <timeOperand> <ws> <allComparisons> <ws> <timeOperand> <ws>

<operand> ::= <stringOperand> | <numericalOperand> | <hexOperand> | <boolOperand> | <dateTimeOperand> | <timeOperand>

<stringOperand> ::=
    <FieldIdentifierString> | <StringLiteral> | <castToString> | <SingleAttribute>

<numericalOperand> ::=
    <NumericalLiteral> | <castToNumerical> | <dateTimeToNum>

<hexOperand> ::=
    <HexLiteral> | <castToHex>

<boolOperand> ::=
    <BoolLiteral> | <castToBool>

<dateTimeOperand> ::=
    <DateTimeLiteral> | <castToDateTime> | <GlobalAttribute>

<timeOperand> ::=
    <TimeLiteral> | <castToTime>

<castToString> ::=
    "str" <ws> "(" <ws> <operand> <ws> ")" <ws>

<castToNumerical> ::=
    "num" <ws> "(" <ws> <operand> <ws> ")" <ws>

<castToHex> ::=
    "hex" <ws> "(" <ws> <operand> <ws> ")" <ws>

<castToBool> ::=
    "bool" <ws> "(" <ws> <operand> <ws> ")" <ws>

<castToDateTime> ::=
    "dateTime" <ws> "(" <ws> <stringOperand> <ws> ")" <ws>

<castToTime> ::=
    "time" <ws> "(" <ws> ( <stringOperand> | <dateTimeOperand> ) <ws> ")" <ws>

<AllAccessPermissionRules> ::=
    ( "DEFATTRIBUTES" <ws> <StringLiteral> <ws> <AttributeGroup> <ws> )*
    ( "DEFACLS" <ws> <StringLiteral> <ws> <ACL> <ws> )*
    ( "DEFOBJECTS" <ws> <StringLiteral> <ws> <ObjectGroup> <ws> )*
    ( "DEFFORMULAS" <ws> <StringLiteral> <ws> <Condition> <ws> )*
    ( <AccessPermissionRule> <ws> )*

<AccessPermissionRule> ::=
    "ACCESSRULE:" <ws>
    ( <ACL> | <UseACL> ) <ws>
    "OBJECTS:" <ws>
    ( <SingleObject> <ws> )*
    ( <UseObjectGroup> <ws> )*
    "FORMULA:" <ws>
    ( <Condition> | <UseFormula> ) <ws>
    ( "FILTER:" <ws> <FragmentObject> <ws> ( <Condition> | <UseFormula> ) <ws> )?

<ACL> ::=
    "ATTRIBUTES:" <ws>
    ( <SingleAttribute> <ws> )*
    ( <UseAttributeGroup> <ws> )*
    "RIGHTS:" <ws> <Right> <ws> ( <Right> <ws> )*
    "ACCESS:" <ws> <Access> <ws>

<UseACL> ::=
    "USEACLS" <ws> <StringLiteral> <ws>

<Right> ::=
    "CREATE" | "READ" | "UPDATE" | "DELETE" | "EXECUTE" | "VIEW" | "ALL" | "TREE"

<Access> ::=
    "ALLOW" | "DISABLED"

<SingleAttribute> ::=
    <ClaimAttribute> | <GlobalAttribute> | <ReferenceAttribute>

<ClaimAttribute> ::=
    "CLAIM" <ws> "(" <ws> <ClaimLiteral> <ws> ")"

<GlobalAttribute> ::=
    "GLOBAL" <ws> "(" <ws> ( "LOCALNOW" | "UTCNOW" | "CLIENTNOW" | "ANONYMOUS" ) <ws> ")"

<ReferenceAttribute> ::=
    "REFERENCE" <ws> "(" <ws> <ReferenceLiteral> <ws> ")"

<AttributeGroup> ::=
    ( <SingleAttribute> <ws> )*
    ( <UseAttributeGroup> <ws> )*

<UseAttributeGroup> ::=
    "USEATTRIBUTES" <ws> <StringLiteral> <ws>

<SingleObject> ::=
    <RouteObject> | <IdentifiableObject> | <ReferableObject> | <FragmentObject> | <DescriptorObject>

<RouteObject> ::=
    "ROUTE" <ws> <RouteLiteral> <ws>

<IdentifiableObject> ::=
    "IDENTIFIABLE" <ws> <IdentifiableLiteral> <ws>

<ReferableObject> ::=
    "REFERABLE" <ws> <ReferableLiteral> <ws>

<FragmentObject> ::=
    "FRAGMENT" <ws> <FragmentLiteral> <ws>

<DescriptorObject> ::=
    "DESCRIPTOR" <ws> <DescriptorLiteral> <ws>

<ObjectGroup> ::=
    ( <SingleObject> <ws> )*
    | ( <UseObjectGroup> <ws> )*

<UseObjectGroup> ::=
    "USEOBJECTS" <ws> <StringLiteral> <ws>

<UseFormula> ::=
    "USEFORMULAS" <ws> <StringLiteral> <ws>

<Condition> ::= <logicalExpression> <ws>

<DateTimeLiteral> ::= <datetime> <ws>
<TimeLiteral> ::= <time> <ws>
<datetime> ::= <date> <ws> ( "T" | " " ) <ws> <time> <ws> ( <timezone> <ws> )?
<date> ::= <year> <ws> "-" <ws> <month> <ws> "-" <ws> <day> <ws>
<year> ::= <digit> <ws> <digit> <ws> <digit> <ws> <digit> <ws>
<month> ::= <digit> <ws> <digit> <ws>
<day> ::= <digit> <ws> <digit> <ws>
<time> ::= <hour> <ws> ":" <ws> <minute> <ws> ( ":" <ws> <second> <ws> )? ( "." <ws> <fraction> <ws> )?
<timezone> ::= ( "Z" | ( "+" | "-" ) <ws> <hour> <ws> ":" <ws> <minute> <ws> )
<hour> ::= <digit> <ws> <digit> <ws>
<minute> ::= <digit> <ws> <digit> <ws>
<second> ::= <digit> <ws> <digit> <ws>
<fraction> ::= <digit>+ <ws>

<digit> ::= [0-9] <ws>
<StringLiteral> ::= "\"" ( [A-Z] | [a-z] | [0-9] | "/" | "*" | "[" | "]" | "(" | ")" | " " | "_" | "@" | "#" | "\\" | "+" | "-" | "." | "," | ":" | "$" | "^" | "*" )+ "\""
<ClaimLiteral> ::= <StringLiteral>
<ReferenceLiteral> ::= <StringLiteral>
<RouteLiteral> ::= <StringLiteral>
<IdentifiableLiteral> ::= <StringLiteral>
<ReferableLiteral> ::= <StringLiteral>
<FragmentLiteral> ::= <StringLiteral>
<DescriptorLiteral> ::= <StringLiteral>
<NumericalLiteral> ::= ( "+" | "-" )? ( [0-9]+ ( "." [0-9]* )? | "." [0-9]+ ) ( ( "e" | "E" )? [0-9]+ )
<HexLiteral> ::= "16#" ( [0-9] | [A-F] )+
<BoolLiteral> ::= "true" | "false"
<FieldIdentifier> ::= <FieldIdentifierString>
<FieldIdentifierString> ::= <FieldIdentifierAAS> | <FieldIdentifierSM> | <FieldIdentifierSME> | <FieldIdentifierCD> | <FieldIdentifierAasDescriptor> | <FieldIdentifierSmDescriptor>
<FieldIdentifierAAS> ::= "$aas#" ( "idShort" | "id" | "assetInformation.assetKind" | "assetInformation.assetType" | "assetInformation.globalAssetId" | "assetInformation." <SpecificAssetIdsClause> | "submodels." <ReferenceClause> )
<FieldIdentifierSM> ::= "$sm#" ( <SemanticIdClause> | "idShort" | "id" )
<FieldIdentifierSME> ::= "$sme" ( "." <idShortPath> )? "#" ( <SemanticIdClause> | "idShort" | "value" | "valueType" | "language" )
<FieldIdentifierCD> ::= "$cd#" ( "idShort" | "id" ) <ws>
<FieldIdentifierAasDescriptor> ::= "$aasdesc#" ( "idShort" | "id" | "assetKind" | "assetType" | "globalAssetId" | <SpecificAssetIdsClause>  | "endpoints" ( "[" ( [0-9]* ) "]" )? "." <EndpointClause> | "submodelDescriptors" ( "[" ( [0-9]* ) "]" )? "." <SmDescriptorClause> )
<FieldIdentifierSmDescriptor> ::= "$smdesc#" <SmDescriptorClause>
<SmDescriptorClause> ::= ( <SemanticIdClause> | "idShort" | "id" | "endpoints" ( "[" ( [0-9]* ) "]" )? "." <EndpointClause> )
<EndpointClause> ::= "interface" | "protocolinformation.href"

<ReferenceClause> ::= ( "type" | "keys" ( "[" ( [0-9]* ) "]" )? ( ".type" | ".value" ) )
<SemanticIdClause> ::= ( "semanticId" | "semanticId." <ReferenceClause> )
<SpecificAssetIdsClause> ::=  ( "specificAssetIds" ( "[" ( [0-9]* ) "]" )? ( ".name" | ".value" | ".externalSubjectId" | ".externalSubjectId." <ReferenceClause> ) )
<idShortPath> ::= ( <idShort> ("[" ( [0-9]* ) "]" )? ( "." <idShortPath> )* )
<idShort> ::= ( ( [a-z] | [A-Z] ) ( [a-z] | [A-Z] | [0-9] | "_" )* )

<ws> ::= ( " " | "\t" | "\r" | "\n" )*

Select Expression

The default return type is a list containing the respective AAS objects. For an AAS Repository, it’s a list of Asset Administration Shells, while a Submodel Registry returns a list of SubmodelDescriptors. The optional $select statement declares whether the response shall deviate from this default behavior, and only return a list of identifiers instead of a list of objects ($select id).

Identification of Fields

Elements relevant for comparisons are described using an adapted IdShortPath notation. The declaration starts with kind of element that shall serve as the root of the expression, followed with an optional '.' as the separator symbol and an optional IdShortPath, and a mandatory declaration of the AAS attribute that shall be examined, separated via '#'. A recursive search is made through the Submodel Elements, when the optional IdShortPath is left out.

FieldIdentifier ::= <RootDeclaration> ( "." <IdShortPath> | "" ) "#" <AttributeDeclaration>

Constraint AASa-005: Only the SubmodelElements root delaration can be followed with IdShortPaths.

Table 1. Root Elements for Field Identifiers

Root Element

Definition

Example(s)

$aas

Starting point for fields available in Asset Administration Shells

$aas#assetInformation.assetKind

$sm

Starting point for fields available in Submodels

$sm#semanticId.keys[0].value

$sme

Starting point for fields available in Submodel Elements. Can be followed with an IdShortPath, see Clause AASa-005. Can start at any possible Submodel Element, is not restricted to Submodel Elements directly in the Submodel/submodelElements list.

$sme.smeCollectionIdShort.propertyIdShort#value, $sme#value to search recursively

$cd

Starting point for fields available in Concept Descriptions

$cd#id

$aasdesc

Starting point for fields available in Asset Administration Shell Descriptors

$aasdesc#submodelDescriptors[0].endpoints[0].protocolinformation.href

$smdesc

Starting point for fields available in Submodel Descriptors

$smdesc#endpoints[0].protocolinformation.href

Attribute declarations point to literal values that provide the input for comparisons. It is not possible to point to objects or lists, only atomic values. Attribute declarations present a subset of the attributes defined by the AAS Metamodel and the extension classes of Clause Data Types for Payload.

Table 2. Attribute Elements for Field Identifiers. <index> is an optional nonNegativeInteger value. No <index> shall be interpreted as 'anywhere in the list'.

Root Element

Definition

Example

id

Identifier, e.g., of an AAS, Submodel, or Condept Description

$aas#id

idShort

Value of the idShort attribute

$aas#id

assetInformation.assetKind

Value of the assetKind attribute of an AAS

$aas#assetInformation.assetKind

assetInformation.assetType

Value of the assetKind attribute of an AAS

$aas#assetInformation.assetType

assetInformation.globalAssetId

Value of the globalAssetId attribute of an AAS

$aas#assetInformation.globalAssetId

assetInformation.assetInformation. specificAssetIds[<index>].name

Name of a SpecificAssetId of an AAS

$aas#assetInformation.assetInformation. specificAssetIds[].name

assetInformation.assetInformation. specificAssetIds[<index>].value

Value of a SpecificAssetId of an AAS

$aas#assetInformation.assetInformation. specificAssetIds[1].value

assetInformation.assetInformation. specificAssetIds[<index>].externalSubjectId. type

Type of a Reference used as an externalSubjectId in a SpecificAssetId of an AAS

$aas#assetInformation.assetInformation. specificAssetIds[0]. externalSubjectId.type

assetInformation.assetInformation. specificAssetIds[<index>].externalSubjectId. keys[<index>].value

Value of a key of a Reference used as an externalSubjectId in a SpecificAssetId of an AAS

$aas#assetInformation.assetInformation. specificAssetIds[0].externalSubjectId. keys[].value

assetInformation.assetInformation. specificAssetIds[<index>].externalSubjectId. keys[<index>].type

Type of a key of a Reference used as an externalSubjectId in a SpecificAssetId of an AAS

$aas#assetInformation.assetInformation. specificAssetIds[0].externalSubjectId. keys[].type

submodels

Shortcut for Submodels referenced by an AAS, see Clause References

$aas#submodels

submodels.type

Type of a Reference that associates an AAS with a Submodel

$aas#submodels.type

submodels.keys[<index>].value

Value of a key used in a Reference that associates an AAS with a Submodel

$aas#submodels.keys[].value

submodels.keys[<index>].type

Value of a key used in a Reference that associates an AAS with a Submodel

$aas#submodels.keys[0].type

semanticId

Shortcut for semanticIds, see Clause References

$sm#semanticId

semanticId.type

ReferenceType of a semanticId Reference

$sm#semanticId.type

semanticId.keys[<index>].type

KeyType of a semanticId Reference

$sm#semanticId.keys[].type

semanticId.keys[<index>].value

Value of a key of a semanticId Reference

$sme#semanticId.keys[].value

value

Value of a Submodel Element

$sme#value

valueType

ValueType of a Submodel Element

$sme.someIdShort#valueType

language

Language of a Multilanguage Property

$sme#language

assetKind

Value of the assetKind attribute of an AAS Descriptor

$aasdesc#assetKind

assetType

Value of the assetKind attribute of an AAS Descriptor

$aasdesc#assetType

globalAssetId

Value of the globalAssetId attribute of an AAS Descriptor

$aasdesc#globalAssetId

specificAssetIds[<index>].name

Name of a SpecificAssetId of an AAS Descriptor

$aasdesc#specificAssetIds[].name

specificAssetIds[<index>].value

Value of a SpecificAssetId of an AAS Descriptor

$aasdesc#specificAssetIds[1].value

specificAssetIds[<index>].externalSubjectId. type

Type of a Reference used as an externalSubjectId in a SpecificAssetId of an AAS Descriptor

$aasdesc#specificAssetIds[<index>]. externalSubjectId.type

specificAssetIds[<index>].externalSubjectId. keys[<index>].value

Value of a key of a Reference used as an externalSubjectId in a SpecificAssetId of an AAS Descriptor

$aasdesc#specificAssetIds[0]. externalSubjectId.keys[].value

specificAssetIds[<index>].externalSubjectId. keys[<index>].type

Type of a key of a Reference used as an externalSubjectId in a SpecificAssetId of an AAS Descriptor

$aasdesc#specificAssetIds[0]. externalSubjectId.keys[].type

endpoints[<index>].interface

Interface of an endpoint of an AAS or Submodel

Note: Can only be used with Asset Administration Shell Descriptors or Submodel Descriptors.

$aasdesc#endpoints[0].interface

endpoints[<index>].protocolinformation.href

Href of an endpoint of an AAS or Submodel

Note: Can only be used with Asset Administration Shell Descriptors or Submodel Descriptors.

$smdesc#endpoints[0]. protocolinformation.href

submodelDescriptors.semanticId

Shortcut for semanticIds, see Clause References

$aasdesc#submodelDescriptors.semanticId

submodelDescriptors.semanticId.type

ReferenceType of a semanticId Reference used in a referenced Submodel of an Asset Administration Shell Descriptor

$aasdesc#submodelDescriptors. semanticId.type

submodelDescriptors.semanticId. keys[<index>].type

KeyType of a semanticId Reference used in a referenced Submodel of an Asset Administration Shell Descriptor

$aasdesc#submodelDescriptors.semanticId. keys[].type

submodelDescriptors.semanticId. keys[<index>].value

Value of a key of a semanticId Reference used in a referenced Submodel of an Asset Administration Shell Descriptor

$aasdesc#submodelDescriptors.semanticId. keys[].value

submodelDescriptors.id

Identifier of a referenced Submodel as available in an Asset Administration Shell Descriptor

$aasdesc#submodelDescriptors.id

submodelDescriptors.idShort

idShort of a referenced Submodel as available in an Asset Administration Shell Descriptor

$aasdesc#submodelDescriptors.idShort

submodelDescriptors.endpoints[<index>]. interface

Endpoint interface of a referenced Submodel as available in an Asset Administration Shell Descriptor

$aasdesc#submodelDescriptors.endpoints[0]. interface

submodelDescriptors.endpoints[<index>]. protocolinformation.href

Endpoint href of a referenced Submodel as available in an Asset Administration Shell Descriptor

$aasdesc#submodelDescriptors.endpoints[]. protocolinformation.href

Comparison Operators

The following comparison operators are part of the query language. The result of a comparison shall always be (a) of type xs:boolean or (b) a comparison error, e.g., due to invalid inputs.
In case of an error the comparison result is invalid. Any further combinations with the invalid result will also have an invalid result. In that case all condition expressions will be ignored for the evaluated element and no result will be returned. Only the elements with valid results will be returned.

The comparisons $eq $ne $gt $lt $ge $le are overloaded in the BNF grammar, which means that the same comparison can deal with several input types. For instance, $eq can be used both for values of type xs:string and xs:int. The comparisons $contains $starts-with $ends-with $regex only allow xs:string.

Operator

Description

Definition

$eq

Compares two values if they are identical.

Operator 'A eq B' in https://www.w3.org/TR/xpath-30/#mapping

$ne

Compares two values if they are not identical.

Operator 'A eq B' in https://www.w3.org/TR/xpath-30/#mapping

$gt

Checks whether one parameter is greater than another.

Operator 'A gt B' in https://www.w3.org/TR/xpath-30/#mapping

$lt

Checks whether one parameter is lower than another.

Operator 'A lt B' in https://www.w3.org/TR/xpath-30/#mapping

$ge

Checks whether one parameter is greater or equal than another.

Operator 'A ge B' in https://www.w3.org/TR/xpath-30/#mapping

$le

Checks whether one parameter is lower or equal than another.

Operator 'A ne B' in https://www.w3.org/TR/xpath-30/#mapping

$contains

Compares two string expressions whether the second parameter appears as a substring inside of the first.

Defined as fn:contains in https://www.w3.org/TR/xpath-functions-30/#func-contains

$starts-with

Compares two string expressions whether the second parameter appears character-equal at the beginning of the first.

Defined as fn:starts-with in https://www.w3.org/TR/xpath-functions-30/#func-starts-with

$ends-with

Compares two string expressions whether the second parameter appears character-equal at the end of the first.

Defined as fn:starts-with in https://www.w3.org/TR/xpath-functions-30/#func-ends-with

$regex

Compares two string expressions whether the first parameter matches the regex of the second.

Defined as fn:starts-with in https://www.w3.org/TR/xpath-functions-30/#func-matches

Example

The following example is used to illustrate the comparisons. The following Asset Administration Shell is used for the evaluations of the different operators.

{
    "modelType": "AssetAdministrationShell",
    "id": "https://example.com/asset-administration-shell-1",
    "assetInformation": {
        "assetKind": "Instance",
        "globalAssetId": "urn:asset-administration-shell-1",
        "specificAssetIds": [
            {
                "name": "supplierId",
                "value": "aas-1"
            },
            {
                "name": "customerId",
                "value": "aas-2"
            }
        ],
    },
    "submodels": [
        {
            "type": "ModelReference",
            "keys": [
                {
                    "type": "Submodel",
                    "value": "https://example.com/submodel-1"
                }
            ]
        },
        {
            "type": "ModelReference",
            "keys": [
                {
                    "type": "Submodel",
                    "value": "https://example.com/submodel-2"
                }
            ]
        }
    ],
}

Comparison

Result

Comment

$aas#idShort
$eq
$aas#assetInformation.assetType

true

Both items are empty, therefore, they are equal.

$aas#idShort
$le
$aas#assetInformation.assetType

true

$eq implies $le

$aas#idShort
$ne
$aas#assetInformation.assetType

false

Both items are empty, therefore, they are equal.

1 $le 2

true

Numeric comparison

1 $gt 2

false

Numeric comparison

13 $eq '13'

false

Type mismatch

"a" $lt "b"

true

String comparison

"1" $gt "2"

false

String comparison

"11" $gt "2"

false

String comparison is executed character-wise: The first character of the left parameter ("1") comes before the first character of the right parameter ("2").

$aas#assetInformation.assetKind
$eq
$aas#submodels

false

$aas#submodels returns the strings https://example.com/submodel-1 and https://example.com/submodel-2, neither is equal to the value of the assetKind = Instance.

$aas#assetInformation.assetKind
$ne
$aas#submodels

true

$aas#submodels returns the strings https://example.com/submodel-1 and https://example.com/submodel-2, neither is equal to the value of the assetKind = Instance.

$aas#assetInformation.assetKind
$eq
$aas#assetInformation.assetKind

true

Comparison of identical values

$aas#assetInformation.assetKind
$ne
$aas#assetInformation.assetKind

false

Comparison of identical values

$aas#submodels $eq $aas#submodels

true

By definition.

$aas#assetInformation.assetKind $eq 17

false

17 is implicetly casted to the string "17", however, this is different to the value of the first paramter "Instance".

$aas#assetInformation.assetKind $ne 17

true

17 is implicetly casted to the string "17", which is not equal to the value of the first paramter "Instance".

$aas#assetInformation.assetKind
$le
$aas#assetInformation.assetKind

true

$eq implies $le

bool("true") $ge bool("true")

true

$eq implies $ge

bool("true") $gt bool("true")

false

Booleans do not offer $lt/$gt comparison

$aas#id
$contains
"https://example.com/asset-administration"

true

"https://example.com/asset-administration" is a substring of the id value ("https://example.com/asset-administration-shell-1")

Logical Expressions

Logical expressions allow the combination of two or more single comparisons through AND or OR relations, and to negate the result of an expression. Furthermore, logical expressions can also be used to combine other logical expressions. Combinations with invalid results will be ignored, as explained above.

Logical Operator

Description

Definition

$and

Connects two or more expressions through a logical AND.

Defined by https://www.w3.org/TR/xpath-30/#doc-xpath30-AndExpr

$or

Connects two or more expressions through a logical OR.

Defined by https://www.w3.org/TR/xpath-30/#doc-xpath30-OrExpr

$not

Negates an expression.

The "not" operator inverts the truth value of its operand. If the operand is true, the result is false, and if the operand is false, the result is true. Defined by https://www.w3.org/TR/xpath-functions-30/#func-not

Paranthesises

Paranthesises ( ) allow to combine logical expressions to define precedence. LogicalExpressions with paranthesises can be nested.

Casting

For explicite casting the following casting operators are used:

Casting Operator

Description

Definition

$str(<value>)

Casts the value to xs:string.

Defined by https://www.w3.org/TR/xpath-functions-30/#func-string

$num(<value>)

Casts the value to xs:integer.

Defined by https://www.w3.org/TR/xpath-functions-30/#func-number

$dateTime(<value>)

Casts the value to xs:dateTime.

Defined by https://www.w3.org/TR/xpath-functions-30/#func-dateTime

$bool(<value>)

Casts the value to xs:boolean.

Defined by https://www.w3.org/TR/xpath-functions-30/#func-boolean

$hex(<value>)

Casts the value to xs:hexBinary.

Defined by https://www.w3.org/TR/xpath-functions/#casting-to-binary

$dateTime(<value>)

Casts the value to xs:dateTime.

Defined by https://www.w3.org/TR/xpath-functions/#casting-to-datetimes

$time(<value>)

Casts the value to xs:time.

Defined by https://www.w3.org/TR/xpath-functions/#casting-to-datetimes

Implicite casting is used together with FieldIdentifiers. FieldIdentifiers are generally treated as xs:string in the query language.
If a FieldIdentifier is used in a logicalExpression, it will be implicitely casted to xs:boolean, which can only create a valid result for the values true and false.
If a FieldIdentifier is used in a comparison, the second parameter decides implicite casting. If the second parameter is a constant (string, number, hex, boolean, dateTime, time) or a corresponding explicite casting operator, the value of the FieldIdentifier will be implicitely casted to the corresponding data type.

Referring to Elements in Lists and Arrays

The AAS Metamodel defines several objects with lists as child elements, e.g., SubmodelElementList/value, AssetInformation/specificAssetIds, or Reference/keys. The AAS Query Language contains two different patterns to refer to elements inside these lists:

Specific Index Notation

In case the position inside the list is known, the query can directly leverage the index number inside square brackets.

<fieldIdentifier>[<index>]

For the first element of a SubmodelElementList with the idShort "smlIdShort", this notation may lead to a following declaration:

$sme.<someIdShortPath>.smlIdShort[0]

For the first key of a semanticId reference, this notation may lead to a following declaration:

$sme.<someIdShortPath>#semanticId.keys[0]

Any Element Notation

In case the position in the list is not known, the index inside the square brackets can be skipped. This means that at least one element has to fulfill the comparison to make the expression evaluate to true.

<fieldIdentifier>[]

To refer to any element inside a SubmodelElementList with the idShort "smlIdShort", this notation may lead to a following declaration:

$sme.<somePath>.smlIdShort[]

For any key of a semanticId reference, this notation may lead to a following declaration:

$sme.<somePath>#semanticId.keys[]

References

References include a list of keys, i.e. .keys[]. Very often the value of the first key in the list is needed, e.g. for semanticId.
To ease writing, .keys[0].value can be left off for References.

semanticId is defined as the "value" of the first key of the semanticId Reference object. The following two expressions are equivilant:

 <somePath>.semanticId
 <somePath>.semanticId.keys[0].value
A comparison using the semanticId as a shortcut could look like the following:

$sme#semanticId $eq "https://example.com/a/semantic/id"

Match of Elements in Lists

The $match operator signals that the following clauses (a) contain at least 1 list of elements with [] syntax, and that (b) all conditions shall be evaluated on the same element of this list. The common path prefix left to a [] determines the list to be searched.

FieldIdentifiers in a $match may contain several [], which define nested lists. In such case the path prefix of the first [] must always be the same and the path prefixes of the following [] accordingly.

$match is similar to $and, since all conditions inside must result to true. But as explained above, [] can be specified in addition.
$match can include $match and comparisions. logicalExpressions are not allowed inside $match.
$match inside $match further restricts the subset of possible elements inside nested [].

Note 1: If the comparisons inside an $match clause contains expressions that are not pointing to the list under consideration, an error shall be returned.

The table illustrates the behavior using the example Asset Administration Shell above.

Comparison

Result

Comment

$match(
  $aas#assetInformation.specificAssetIds[].name
    $eq "supplierId",
  $aas#assetInformation.specificAssetIds[].value
    $eq "aas-1"
)
[
  {
    "modelType": "AssetAdministrationShell",
    "id": "https://example.com/asset-administration-shell-1",
    ...
  }
]

The values for 'supplierId' and 'aas-1' exist in the same SpecificAssetId object.

$match(
  $aas#assetInformation.specificAssetIds[].name
    $eq "supplierId",
  $aas#assetInformation.specificAssetIds[].value
    $eq "aas-2"
)

[ ]

The values for 'supplierId' and 'aas-2' do not exist in the same SpecificAssetId object.

$and (
  $aas#assetInformation.specificAssetIds[].name
    $eq "supplierId",
  $aas#assetInformation.specificAssetIds[].value
    $eq "aas-2"
)
[
  {
    "modelType": "AssetAdministrationShell",
    "id": "https://example.com/asset-administration-shell-1",
    ...
  }
]

The values for 'supplierId' and 'aas-2' exist in the example AAS, even though in different SpecificAssetId objects. As no $match enforces the evaluation on the same SpecificAssetId, the AAS from the example fulfils the condition.

$or (
  $match (
    $aas#assetInformation.specificAssetIds[]
    .name    $eq   "supplierId",
    $aas#assetInformation.specificAssetIds[]
    .value   $eq   "aas-1"
  ),
  $match (
    $aas#assetInformation.specificAssetIds[]
    .name    $eq   "customerId",
    $aas#assetInformation.specificAssetIds[]
    .value   $eq   "aas-2"
  )
)
[
  {
    "modelType": "AssetAdministrationShell",
    "id": "https://example.com/asset-administration-shell-1",
    ...
  }
]

Both $match conditions are fulfilled, even though for different SpecificAssetIds. Therefore the OR clause also evaluates to true for both items.

Sorting and Pagination

The AAS Query Language does not introduce additional functionalities to control the pagination or sorting of the result sets. The general capabilities available for Operations apply as well for queries.

JSON Schema

The AAS HTTP API represents AAS Queries as JSON objects. A JSON schema according to the grammar above has been defined. This JSON schema allows immediate validation of queries but also automatic code generation which has been validated with jsonschema2pojo. To allow such automatic code generation, polymorhism by the use of oneOf in the JSON schema must be avoided.
In addition, several constructs introduced in BNF form require a slightly differing representation. For instance, a basic comparison follows the pattern <operand> <operator> <operand> but appears as "<operator>": [<operand>, <operand>] in the JSON representation. JSON schema allows to use regular expressions. Such regular expressions are used to validate the syntax of FieldIdentifiers. To be able to use common JSON schema validators, the depth and details have been limited in the corresponding regular expressions.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Common JSON Schema for AAS Queries and Access Rules",
  "description": "This schema contains all classes that are shared between the AAS Query Language and the AAS Access Rule Language.",
  "definitions": {
    "standardString": {
      "type": "string",
      "pattern": "^(?!\\$).*"
    },
    "modelStringPattern": {
      "type": "string",
      "pattern": "^((?:\\$aas#(?:idShort|id|assetInformation\\.assetKind|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.(?:specificAssetIds(\\[[0-9]*\\])(?:\\.(?:name|value|externalSubjectId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(?:type|value))?)?)?)|submodels\\.(?:type|keys\\[\\d*\\](?:\\.(?:type|value))?))|submodels\\.(type|keys\\[\\d*\\](?:\\.(type|value))?)))|(?:\\$sm#(?:semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|id))|(?:\\$sme(?:\\.[a-zA-Z][a-zA-Z0-9_]*(\\[[0-9]*\\])?(?:\\.[a-zA-Z][a-zA-Z0-9_]*(\\[[0-9]*\\])?)*)?#(?:semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|value|valueType|language))|(?:\\$cd#(?:idShort|id))|(?:\\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds(\\[[0-9]*\\])?(?:\\.(name|value|externalSubjectId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?)?)|endpoints(\\[[0-9]*\\])\\.(interface|protocolinformation\\.href)|submodelDescriptors(\\[[0-9]*\\])\\.(semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|id|endpoints(\\[[0-9]*\\])\\.(interface|protocolinformation\\.href))))|(?:\\$smdesc#(?:semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|id|endpoints(\\[[0-9]*\\])\\.(interface|protocolinformation\\.href))))$"
    },
    "hexLiteralPattern": {
      "type": "string",
      "pattern": "^16#[0-9A-F]+$"
    },
    "dateTimeLiteralPattern": {
      "type": "string",
      "format": "date-time"
    },
    "timeLiteralPattern": {
      "type": "string",
      "pattern": "^[0-9][0-9]:[0-9][0-9](:[0-9][0-9])?$"
    },
    "Value": {
      "type": "object",
      "properties": {
        "$field": {
          "$ref": "#/definitions/modelStringPattern"
        },
        "$strVal": {
          "$ref": "#/definitions/standardString"
        },
        "$attribute": {
          "$ref": "#/definitions/attributeItem"
        },
        "$numVal": {
          "type": "number"
        },
        "$hexVal": {
          "$ref": "#/definitions/hexLiteralPattern"
        },
        "$dateTimeVal": {
          "$ref": "#/definitions/dateTimeLiteralPattern"
        },
        "$timeVal": {
          "$ref": "#/definitions/timeLiteralPattern"
        },
        "$boolean": {
          "type": "boolean"
        },
        "$strCast": {
          "$ref": "#/definitions/Value"
        },
        "$numCast": {
          "$ref": "#/definitions/Value"
        },
        "$hexCast": {
          "$ref": "#/definitions/Value"
        },
        "$boolCast": {
          "$ref": "#/definitions/Value"
        },
        "$dateTimeCast": {
          "$ref": "#/definitions/Value"
        },
        "$timeCast": {
          "$ref": "#/definitions/Value"
        },
        "$dayOfWeek": {
          "$ref": "#/definitions/dateTimeLiteralPattern"
        },
        "$dayOfMonth": {
          "$ref": "#/definitions/dateTimeLiteralPattern"
        },
        "$month": {
          "$ref": "#/definitions/dateTimeLiteralPattern"
        },
        "$year": {
          "$ref": "#/definitions/dateTimeLiteralPattern"
        }
      },
      "oneOf": [
        {
          "required": [
            "$field"
          ]
        },
        {
          "required": [
            "$strVal"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        },
        {
          "required": [
            "$numVal"
          ]
        },
        {
          "required": [
            "$hexVal"
          ]
        },
        {
          "required": [
            "$dateTimeVal"
          ]
        },
        {
          "required": [
            "$timeVal"
          ]
        },
        {
          "required": [
            "$boolean"
          ]
        },
        {
          "required": [
            "$strCast"
          ]
        },
        {
          "required": [
            "$numCast"
          ]
        },
        {
          "required": [
            "$hexCast"
          ]
        },
        {
          "required": [
            "$boolCast"
          ]
        },
        {
          "required": [
            "$dateTimeCast"
          ]
        },
        {
          "required": [
            "$timeCast"
          ]
        },
        {
          "required": [
            "$dayOfWeek"
          ]
        },
        {
          "required": [
            "$dayOfMonth"
          ]
        },
        {
          "required": [
            "$month"
          ]
        },
        {
          "required": [
            "$year"
          ]
        }
      ],
      "additionalProperties": false
    },
    "stringValue": {
      "type": "object",
      "properties": {
        "$field": {
          "$ref": "#/definitions/modelStringPattern"
        },
        "$strVal": {
          "$ref": "#/definitions/standardString"
        },
        "$strCast": {
          "$ref": "#/definitions/Value"
        },
        "$attribute": {
          "$ref": "#/definitions/attributeItem"
        }
      },
      "oneOf": [
        {
          "required": [
            "$field"
          ]
        },
        {
          "required": [
            "$strVal"
          ]
        },
        {
          "required": [
            "$strCast"
          ]
        },
        {
          "required": [
            "$attribute"
          ]
        }
      ],
      "additionalProperties": false
    },
    "comparisonItems": {
      "type": "array",
      "minItems": 2,
      "maxItems": 2,
      "items": {
        "$ref": "#/definitions/Value"
      }
    },
    "stringItems": {
      "type": "array",
      "minItems": 2,
      "maxItems": 2,
      "items": {
        "$ref": "#/definitions/stringValue"
      }
    },
    "matchExpression": {
      "type": "object",
      "properties": {
        "$match": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/matchExpression"
          }
        },
        "$eq": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$ne": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$gt": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$ge": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$lt": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$le": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$contains": {
          "$ref": "#/definitions/stringItems"
        },
        "$starts-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$ends-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$regex": {
          "$ref": "#/definitions/stringItems"
        },
        "$boolean": {
          "type": "boolean"
        }
      },
      "oneOf": [
        {
          "required": [
            "$eq"
          ]
        },
        {
          "required": [
            "$ne"
          ]
        },
        {
          "required": [
            "$gt"
          ]
        },
        {
          "required": [
            "$ge"
          ]
        },
        {
          "required": [
            "$lt"
          ]
        },
        {
          "required": [
            "$le"
          ]
        },
        {
          "required": [
            "$contains"
          ]
        },
        {
          "required": [
            "$starts-with"
          ]
        },
        {
          "required": [
            "$ends-with"
          ]
        },
        {
          "required": [
            "$regex"
          ]
        },
        {
          "required": [
            "$boolean"
          ]
        },
        {
          "required": [
            "$match"
          ]
        }
      ],
      "additionalProperties": false
    },
    "logicalExpression": {
      "type": "object",
      "properties": {
        "$and": {
          "type": "array",
          "minItems": 2,
          "items": {
            "$ref": "#/definitions/logicalExpression"
          }
        },
        "$match": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/definitions/matchExpression"
          }
        },
        "$or": {
          "type": "array",
          "minItems": 2,
          "items": {
            "$ref": "#/definitions/logicalExpression"
          }
        },
        "$not": {
          "$ref": "#/definitions/logicalExpression"
        },
        "$eq": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$ne": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$gt": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$ge": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$lt": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$le": {
          "$ref": "#/definitions/comparisonItems"
        },
        "$contains": {
          "$ref": "#/definitions/stringItems"
        },
        "$starts-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$ends-with": {
          "$ref": "#/definitions/stringItems"
        },
        "$regex": {
          "$ref": "#/definitions/stringItems"
        },
        "$boolean": {
          "type": "boolean"
        }
      },
      "oneOf": [
        {
          "required": [
            "$and"
          ]
        },
        {
          "required": [
            "$or"
          ]
        },
        {
          "required": [
            "$not"
          ]
        },
        {
          "required": [
            "$eq"
          ]
        },
        {
          "required": [
            "$ne"
          ]
        },
        {
          "required": [
            "$gt"
          ]
        },
        {
          "required": [
            "$ge"
          ]
        },
        {
          "required": [
            "$lt"
          ]
        },
        {
          "required": [
            "$le"
          ]
        },
        {
          "required": [
            "$contains"
          ]
        },
        {
          "required": [
            "$starts-with"
          ]
        },
        {
          "required": [
            "$ends-with"
          ]
        },
        {
          "required": [
            "$regex"
          ]
        },
        {
          "required": [
            "$boolean"
          ]
        },
        {
          "required": [
            "$match"
          ]
        }
      ],
      "additionalProperties": false
    },
    "attributeItem": {
      "oneOf": [
        {
          "required": [
            "CLAIM"
          ]
        },
        {
          "required": [
            "GLOBAL"
          ]
        },
        {
          "required": [
            "REFERENCE"
          ]
        }
      ],
      "properties": {
        "CLAIM": {
          "type": "string"
        },
        "GLOBAL": {
          "type": "string",
          "enum": [
            "LOCALNOW",
            "UTCNOW",
            "CLIENTNOW",
            "ANONYMOUS"
          ]
        },
        "REFERENCE": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "objectItem": {
      "oneOf": [
        {
          "required": [
            "ROUTE"
          ]
        },
        {
          "required": [
            "IDENTIFIABLE"
          ]
        },
        {
          "required": [
            "REFERABLE"
          ]
        },
        {
          "required": [
            "FRAGMENT"
          ]
        },
        {
          "required": [
            "DESCRIPTOR"
          ]
        }
      ],
      "properties": {
        "ROUTE": {
          "type": "string"
        },
        "IDENTIFIABLE": {
          "type": "string"
        },
        "REFERABLE": {
          "type": "string"
        },
        "FRAGMENT": {
          "type": "string"
        },
        "DESCRIPTOR": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "rightsEnum": {
      "type": "string",
      "enum": [
        "CREATE",
        "READ",
        "UPDATE",
        "DELETE",
        "EXECUTE",
        "VIEW",
        "ALL",
        "TREE"
      ],
      "additionalProperties": false
    },
    "ACL": {
      "type": "object",
      "properties": {
        "ATTRIBUTES": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/attributeItem"
          }
        },
        "USEATTRIBUTES": {
          "type": "string"
        },
        "RIGHTS": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/rightsEnum"
          }
        },
        "ACCESS": {
          "type": "string",
          "enum": [
            "ALLOW",
            "DISABLED"
          ]
        }
      },
      "required": [
        "RIGHTS",
        "ACCESS"
      ],
      "oneOf": [
        {
          "required": [
            "ATTRIBUTES"
          ]
        },
        {
          "required": [
            "USEATTRIBUTES"
          ]
        }
      ],
      "additionalProperties": false
    },
    "AccessPermissionRule": {
      "type": "object",
      "properties": {
        "ACL": {
          "$ref": "#/definitions/ACL"
        },
        "USEACL": {
          "type": "string"
        },
        "OBJECTS": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/objectItem"
          },
          "additionalProperties": false
        },
        "USEOBJECTS": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "FORMULA": {
          "$ref": "#/definitions/logicalExpression",
          "additionalProperties": false
        },
        "USEFORMULA": {
          "type": "string"
        },
        "FRAGMENT": {
          "type": "string"
        },
        "FILTER": {
          "$ref": "#/definitions/logicalExpression",
          "additionalProperties": false
        },
        "USEFILTER": {
          "type": "string"
        }
      },
      "oneOf": [
        {
          "required": [
            "ACL"
          ]
        },
        {
          "required": [
            "USEACL"
          ]
        }
      ],
      "oneOf": [
        {
          "required": [
            "OBJECTS"
          ]
        },
        {
          "required": [
            "USEOBJECTS"
          ]
        }
      ],
      "oneOf": [
        {
          "required": [
            "FORMULA"
          ]
        },
        {
          "required": [
            "USEFORMULA"
          ]
        }
      ],
      "additionalProperties": false
    }
  },
  "type": "object",
  "properties": {
    "Query": {
      "type": "object",
      "properties": {
        "$select": {
          "type": "string",
          "pattern": "^id$"
        },
        "$condition": {
          "$ref": "#/definitions/logicalExpression"
        }
      },
      "required": [
        "$condition"
      ],
      "additionalProperties": false
    },
    "AllAccessPermissionRules": {
      "type": "object",
      "properties": {
        "DEFATTRIBUTES": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "attributes": {
                "type": "array",
                "items": {
                  "$ref": "#/definitions/attributeItem"
                }
              }
            },
            "required": [
              "name",
              "attributes"
            ],
            "additionalProperties": false
          }
        },
        "DEFACLS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "acl": {
                "$ref": "#/definitions/ACL"
              }
            },
            "required": [
              "name",
              "acl"
            ],
            "additionalProperties": false
          }
        },
        "DEFOBJECTS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "objects": {
                "type": "array",
                "items": {
                  "$ref": "#/definitions/objectItem"
                }
              },
              "USEOBJECTS": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "name"
            ],
            "oneOf": [
              {
                "required": [
                  "objects"
                ]
              },
              {
                "required": [
                  "USEOBJECTS"
                ]
              }
            ],
            "additionalProperties": false
          }
        },
        "DEFFORMULAS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "formula": {
                "$ref": "#/definitions/logicalExpression"
              }
            },
            "required": [
              "name",
              "formula"
            ],
            "additionalProperties": false
          }
        },
        "rules": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/AccessPermissionRule"
          }
        }
      },
      "required": [
        "rules"
      ],
      "additionalProperties": false
    }
  },
  "oneOf": [
    {
      "required": [
        "Query"
      ]
    },
    {
      "required": [
        "AllAccessPermissionRules"
      ]
    }
  ],
  "additionalProperties": false
}

The table below explains the mapping between the grammar and the JSON schema. The table follows the structure of the JSON schema top to bottom.

JSON Schema

Grammar

Comment

modelStringPattern

<FieldIdentifier>

AAS model elements are strings which start with a $

standardString

All other value strings

hexLiteralPattern

<HexLiteral>

dateTimeLiteralPattern

<DateTimeLiteral>

timeLiteralPattern

<TimeLiteral>

Value

<operand>

Comparisons eq, ne, gt, ge, lt, le; explicit properties for automatic code generation: strModel etc.

stringValue

<stringOperand>

String operations contains, starts-with, ends-with, regex; explicit properties for automatic code generation: strModel etc.

$field

-

string following the modelStringPattern

$strVal

-

string following the standardString

$attribute

-

explained in Security Access Rules; not used for query language

$numVal

<NumericalLiteral>

Number constant

$hexVal

<HexLiteral>

Hex number constant

$dateTimeVal

<DateTimeLiteral>

DateTime constant

$timeVal

<TimeLiteral>

Time constant

$boolean

<BoolLiteral>

Boolean constant

$strCast

<castToString>

any Value can be used as input

$numCast

<castToNumerical>

any Value can be used as input

$hexCast

<castToHex>

any Value can be used as input

$boolCast

<castToBool>

any Value can be used as input

$dateTimeCast

<castToDateTime>

any Value can be used as input

$timeCast

<castToTime>

any Value can be used as input

$dayOfWeek

<dateTimeToNum>

extract day of week from DateTime; needed for Security Access Rules

$dayOfMonth

<dateTimeToNum>

extract day of month from DateTime; needed for Security Access Rules

$month

<dateTimeToNum>

extract month from DateTime; needed for Security Access Rules

$year

<dateTimeToNum>

extract year from DateTime; needed for Security Access Rules

comparisonItems

-

Comparisons eq, ne, gt, ge, lt, le

stringItems

-

String operations contains, starts-with, ends-with, regex

matchExpression

<matchExpression>

nested match and comparisons and string operations

logicalExpression

<logicalExpression>

nested logicalExpression (including match) and comparisons and string operations

attributeItem

-

explained in Security Access Rules; not used for query language

ACL

-

explained in Security Access Rules; not used for query language

rightsEnum

-

explained in Security Access Rules; not used for query language

AccessPermissionRule

-

explained in Security Access Rules; not used for query language

AllAccessPermissionRules

-

explained in Security Access Rules; not used for query language

$condition

<logicalExpression>

Root object for the query condition expression

$select

<selectStatement>

Optional expresion to control the returned fields. Only 'id' is possible.

Examples for Grammar and JSON Schema

Single comparison

Grammar

JSON Schema

$aas#idShort

$eq

$aas#assetInformation.assetType
{
  "$condition": {
    "$eq": [
      { "$field": "$aas#idShort" },
      {
        "$field":
            "$aas#assetInformation.assetType"
      }
    ]
  }
}

HandoverDocumentation with VDI 2770 Class 03-01 Commissioning and language NL (as expected with SubmodelElementList)+

Grammar

JSON Schema

$match(
  $sme.Documents[].DocumentClassification
    .Class#value   $eq  "03-01",
  $sme.Documents[].DocumentVersion.
    SMLLanguages[]#language  $eq  "nl"
)
{
  "$condition": {
    "$match": [
      { "$eq": [
          { "$field": "$sme.Documents[].
            DocumentClassification.Class
            #value" },
          { "$strVal": "03-01" }
        ]
      },
      { "$eq": [
          { "$field": "$sme.Documents[].
            DocumentVersion.SMLLanguages[]
            #language" },
          { "$strVal": "nl" }
        ]
      }
    ]
  }
}

TechnicalData with motor starter (ECLASS ClassId = 27-37-09-05) and width less than 100 mm

Grammar

JSON Schema

$and(
	$match(
		$sm#idShort $eq "TechnicalData",
		$sme.ProductClassifications
            .ProductClassificationItem
            .ProductClassId#value
        $eq   "27-37-09-05"
	),
	$match(
		$sm#idShort $eq "TechnicalData",
		$sme#semanticId $eq
            "0173-1#02-BAF016#006",
		$sme#value $lt 100
	)
)
{
  "$condition": {
    "$and": [
      { "$match": [
          { "$eq": [
              { "$field": "$sm#idShort" },
              { "$strVal": "TechnicalData" }
            ]
          },
          { "$eq": [
              {
                "$field":
                "$sme.ProductClassifications
                  .ProductClassificationItem
                  .ProductClassId#value"
              },
              { "$strVal": "27-37-09-05" }
            ]
          }
        ]
      },
      { "$match": [
          {
            "$eq": [
              { "$field": "$sm#idShort" },
              { "$strVal": "TechnicalData" }
            ]
          },
          {
            "$eq": [
              { "$field": "$sme#semanticId" },
              { "$strVal": "0173-1#02-BAF016#006" }
            ]
          },
          {
            "$lt": [
              { "$field": "$sme#value" },
              { "$numVal": 100 }
            ]
          }
        ]
      }
    ]
  }
}

Match specificAssetIDs

Grammar

JSON Schema

$or (
  $match (
    $aas#assetInformation.specificAssetIds[]
      .name     $eq   "supplierId",
    $aas#assetInformation.specificAssetIds[]
      .value    $eq   "aas-1"
  ),

  $match (
    $aas#assetInformation.specificAssetIds[]
      .name     $eq   "customerId",
    $aas#assetInformation.specificAssetIds[]
      .value    $eq   "aas-2"
  )
)
{
  "$condition": {
    "$or": [
      {
        "$match": [
          { "$eq": [
              { "$field": "$aas#assetInformation.
              specificAssetIds[].name" },
              { "$strVal": "supplierId" }
            ]
          },
          { "$eq": [
              { "$field": "$aas#assetInformation
              .specificAssetIds[].value" },
              { "$strVal": "aas-1" }
            ]
          }
        ]
      },
      {
        "$match": [
          {
            "$eq": [
              { "$field": "$aas#assetInformation
              .specificAssetIds[].name" },
              { "$strVal": "customerId" }
            ]
          },
          {
            "$eq": [
              { "$field": "$aas#assetInformation
              .specificAssetIds[].value" },
              { "$strVal": "aas-2" }
            ]
          }
        ]
      }
    ]
  }
}

1. For easier reading only the standard paths are shown in the following: $metadata, $value, $reference and $path parameter paths are additionally contained in the OpenAPI file.