The ModelParser
class is used to determine whether one or more DTDL models are valid, to identify specific modeling errors, and to enable inspection of model contents.
This tutorial walks through an aspect of the third use: how to inspect complex schema elements in the object model.
This tutorial specifically inspects complex schemas embedded in contents.
Two related tutorials inspect complex schemas referenced by contents and standard complex schemas referenced by contents.
To parse a DTDL model, you need to instantiate a ModelParser
.
No arguments are required.
var modelParser = new ModelParser();
The DTDL language is syntactically JSON.
The ModelParser
expects a single string or an enumeration of strings.
The single string or each value in the enumeration is JSON text of a DTDL model.
string jsonText =
@"{
""@context"": ""dtmi:dtdl:context;3"",
""@id"": ""dtmi:example:anInterface;1"",
""@type"": ""Interface"",
""contents"": [
{
""@type"": ""Property"",
""name"": ""totalLength"",
""schema"": ""double""
},
{
""@type"": ""Telemetry"",
""name"": ""lengthPerSegment"",
""schema"": {
""@type"": ""Array"",
""elementSchema"": ""double""
}
}
]
}";
The main synchronous method on the ModelParser
is Parse()
.
One argument is required, which can be either a string or an enumeration of strings containing the JSON text to parse as DTDL.
If the submitted model is complete and valid, no exception will be thrown.
Proper code should catch and process exceptions as shown in other tutorials such as this one, but for simplicity the present tutorial omits exception handling.
IReadOnlyDictionary<Dtmi, DTEntityInfo> objectModel = modelParser.Parse(jsonText);
The Interface element can be looked up in the object model by its identifier:
var anInterfaceId = new Dtmi("dtmi:example:anInterface;1");
var anInterface = (DTInterfaceInfo)objectModel[anInterfaceId];
Each of the content values can be accessed by name via the Contents
property on DTInterfaceInfo
:
string totalLengthName = "totalLength";
var totalLength = (DTPropertyInfo)anInterface.Contents[totalLengthName];
string lengthPerSegmentName = "lengthPerSegment";
var lengthPerSegment = (DTTelemetryInfo)anInterface.Contents[lengthPerSegmentName];
The Property "totalLength" has a primitive schema, so it can be accessed in a single step:
Console.WriteLine($"totalLength schema is {totalLength.Schema.Id}");
This snippet displays:
totalLength schema is dtmi:dtdl:instance:Schema:double;2
The identifier dtmi:dtdl:instance:Schema:double;2 represents an element in the DTDL language model for the schema 'double'.
If we care to, we can map this identifier back to the term used in the JSON text of the DTDL model by using the ModelParser.GetTermOrUri()
static method:
Console.WriteLine($"totalLength schema term is {ModelParser.GetTermOrUri(totalLength.Schema.Id)}");
This snippet displays:
totalLength schema term is double
The Telemetry "lengthPerSegment" has a complex schema, so its value is less intuitively clear:
Console.WriteLine($"lengthPerSegment schema is {lengthPerSegment.Schema.Id}");
This snippet displays:
lengthPerSegment schema is dtmi:example:anInterface:_contents:__lengthPerSegment:_schema;1
The identifier dtmi:example:anInterface:_contents:__lengthPerSegment:_schema;1 is auto-generated by the ModelParser
following rules that guarantee its uniqueness.
Reading right-to-left, this identifier means that this is the "schema" for the "lengthPerPathSegment" element of the "contents" property of "dtmi:example:anInterface;1".
The identifer does not indicate what this schema actually is.
To obtain this information, we have to dig deeper into the object model.
The DTDL type of each element is expressed via the property EntityKind
on the DTEntityInfo
base class, which has type enum DTEntityKind
.
We can use this property to determine the complex schema type:
Console.WriteLine($"lengthPerSegment schema type is {lengthPerSegment.Schema.EntityKind}");
This snippet displays:
lengthPerSegment schema type is Array
By casting the schema element to a DTArrayInfo, we can inspect its ElementSchema property:
var lengthPerSegmentSchema = (DTArrayInfo)lengthPerSegment.Schema;
Console.WriteLine($"array elementSchema is {lengthPerSegmentSchema.ElementSchema.Id}");
This snippet displays:
array elementSchema is dtmi:dtdl:instance:Schema:double;2
This is the same primitive schema that Property "totalLength" has directly.