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 referenced by contents.
Two related tutorials inspect complex schemas embedded in 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"",
""schemas"": [
{
""@id"": ""dtmi:example:allotment;1"",
""@type"": ""Map"",
""mapKey"": {
""name"": ""item"",
""schema"": ""string""
},
""mapValue"": {
""name"": ""count"",
""schema"": ""integer""
}
}
],
""contents"": [
{
""@type"": ""Property"",
""name"": ""expectedAllotment"",
""schema"": ""dtmi:example:allotment;1""
},
{
""@type"": ""Telemetry"",
""name"": ""runningAllotment"",
""schema"": ""dtmi:example:allotment;1""
}
]
}";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 expectedAllotmentName = "expectedAllotment";
var expectedAllotment = (DTPropertyInfo)anInterface.Contents[expectedAllotmentName];
string runningAllotmentName = "runningAllotment";
var runningAllotment = (DTTelemetryInfo)anInterface.Contents[runningAllotmentName];The Property "expectedAllotment" and the Telemetry "runningAllotment" both have the same schema value.
This can be seen in the JSON text above, and it can also be accessed via the Schema property on each object:
Console.WriteLine($"expectedAllotment schema is {expectedAllotment.Schema.Id}");
Console.WriteLine($"runningAllotment schema is {runningAllotment.Schema.Id}");This snippet displays:
expectedAllotment schema is dtmi:example:allotment;1
runningAllotment schema is dtmi:example:allotment;1As can be seen in the JSON text above, a complex schema element with identifier "dtmi:example:allotment;1" is defined in the "schemas" property of "dtmi:example:anInterface;1". To obtain information about this complex schema element, we can look in 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.
We can access the complex schema element as expectedAllotment.Schema or as runningAllotment.Schema, since they both point to the same element.
However, for this tutorial, will illustrate accessing the complex schema element by identifier:
var allotmentId = new Dtmi("dtmi:example:allotment;1");
var allotment = objectModel[allotmentId];
Console.WriteLine($"allotment type is {allotment.EntityKind}");This snippet displays:
allotment type is MapThis is the same output we would see from either of the following lines:
Console.WriteLine($"allotment type is {expectedAllotment.Schema.EntityKind}");
Console.WriteLine($"allotment type is {runningAllotment.Schema.EntityKind}");Which display:
allotment type is Map
allotment type is MapBy casting the schema element to a DTMapInfo, we can inspect its properties:
var allotmentMap = (DTMapInfo)allotment;
Console.WriteLine($"map key name is {allotmentMap.MapKey.Name}");
Console.WriteLine($"map key schema is {allotmentMap.MapKey.Schema.Id}");
Console.WriteLine($"map value name is {allotmentMap.MapValue.Name}");
Console.WriteLine($"map value schema is {allotmentMap.MapValue.Schema.Id}");This snippet displays:
map key name is item
map key schema is dtmi:dtdl:instance:Schema:string;2
map value name is count
map value schema is dtmi:dtdl:instance:Schema:integer;2The identifiers dtmi:dtdl:instance:Schema:string;2 and dtmi:dtdl:instance:Schema:integer;2 represent elements in the DTDL language model for the schemas 'string' and 'integer', respectively.
If we care to, we can map these identifiers back to the terms used in the JSON text of the DTDL model by using the ModelParser.GetTermOrUri() static method:
Console.WriteLine($"map key schema term is {ModelParser.GetTermOrUri(allotmentMap.MapKey.Schema.Id)}");
Console.WriteLine($"map value schema term is {ModelParser.GetTermOrUri(allotmentMap.MapValue.Schema.Id)}");This snippet displays:
map key schema term is string
map value schema term is integer