Parse and validate models with the DTDL parser library
This article describes how to parse and validate Azure Digital Twins models using the DTDL validator sample or the .NET parser library.
Models in Azure Digital Twins are defined using the JSON-LD-based Digital Twins Definition language (DTDL). It is recommended to validate your models offline before uploading them to your Azure Digital Twins instance.
To help you validate your models, a .NET client-side DTDL parsing library is provided on NuGet: Microsoft.Azure.DigitalTwins.Parser.
You can use the parser library directly in your C# code, or use the language-agnostic code sample project that is built on the parser library: DTDL Validator sample.
Use the DTDL validator sample
The DTDL Validator is a sample project that can validate model documents to make sure the DTDL is valid. It's built on the .NET parser library and is language-agnostic.
You can view the code in GitHub by selecting the Browse code button at the sample link, and you can download the project from GitHub by selecting the Code button followed by Download ZIP.
The source code shows examples for how to use the parser library. You can use the validator sample as a command line utility to validate a directory tree of DTDL files. It also provides an interactive mode.
In the folder for the DTDL Validator sample, see the readme.md file for instructions on how to package the sample into a self-contained executable.
After you have built a self-contained package and added the executable to your path, you can run the validator with this command in a console on your machine:
DTDLValidator
With the default options, the sample will search for .json files in the current directory and all subdirectories. You can also add the following option to have the sample search in the indicated directory and all subdirectories for files with the extension .dtdl:
DTDLValidator -d C:\Work\DTDL -e dtdl
You can add the -i option for the sample to enter interactive mode:
DTDLValidator -i
For more information about this sample, see the source code or run DTDLValidator --help.
Use the .NET parser library
The Microsoft.Azure.DigitalTwins.Parser library provides model access to the DTDL definitions, essentially acting as the equivalent of C# reflection for DTDL. This library can be used independently of any Azure Digital Twins SDK, especially for DTDL validation in a visual or text editor. It's useful for making sure your model definition files are valid before you try to upload them to the service.
To use the parser library, you provide it with a set of DTDL documents. Typically, you would retrieve these model documents from the service, but you might also have them available locally, if your client was responsible for uploading them to the service in the first place.
Here's the general workflow for using the parser:
- Retrieve some or all DTDL documents from the service.
- Pass the returned, in-memory DTDL documents to the parser.
- The parser will validate the set of documents passed to it, and return detailed error information. This ability is useful in editor scenarios.
- Use the parser APIs to continue analyzing the models included in the document set.
The capabilities of the parser include:
- Get all implemented model interfaces (the contents of the interface's
extendssection). - Get all properties, telemetry, commands, components, and relationships declared in the model. This command also gets all metadata included in these definitions, and takes inheritance (
extendssections) into account. - Get all complex model definitions.
- Determine whether a model is assignable from another model.
Note
IoT Plug and Play devices use a small syntax variant to describe their functionality. This syntax variant is a semantically compatible subset of the DTDL that is used in Azure Digital Twins. When using the parser library, you do not need to know which syntax variant was used to create the DTDL for your digital twin. The parser will always, by default, return the same model for both IoT Plug and Play and Azure Digital Twins syntax.
Code with the parser library
You can use the parser library directly, for things like validating models in your own application or for generating dynamic, model-driven UI, dashboards, and reports.
To support the parser code example below, consider several models defined in an Azure Digital Twins instance:
[
{
"@context": "dtmi:dtdl:context;2",
"@id": "dtmi:com:contoso:coffeeMaker;1",
"@type": "Interface",
"contents": [
{
"@type": "Component",
"name": "coffeeMaker",
"schema": "dtmi:com:contoso:coffeeMakerInterface;1"
}
]
},
{
"@context": "dtmi:dtdl:context;2",
"@id": "dtmi:com:contoso:coffeeMakerInterface;1",
"@type": "Interface",
"contents": [
{
"@type": "Property",
"name": "waterTemp",
"schema": "double"
}
]
},
{
"@context": "dtmi:dtdl:context;2",
"@id": "dtmi:com:contoso:coffeeBar;1",
"@type": "Interface",
"contents": [
{
"@type": "Relationship",
"name": "foo",
"target": "dtmi:com:contoso:coffeeMaker;1"
},
{
"@type": "Property",
"name": "capacity",
"schema": "integer"
}
]
}
]
The following code shows an example of how to use the parser library to reflect on these definitions in C#:
using Azure;
using Azure.DigitalTwins.Core;
using Microsoft.Azure.DigitalTwins.Parser;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DigitalTwins_Samples
{
public class ParseModelsSample
{
public async Task ParseDemoAsync(DigitalTwinsClient client)
{
try
{
AsyncPageable<DigitalTwinsModelData> mdata = client.GetModelsAsync(new GetModelsOptions { IncludeModelDefinition = true });
var models = new List<string>();
await foreach (DigitalTwinsModelData md in mdata)
models.Add(md.DtdlModel);
var parser = new ModelParser();
IReadOnlyDictionary<Dtmi, DTEntityInfo> dtdlOM = await parser.ParseAsync(models);
var interfaces = new List<DTInterfaceInfo>();
IEnumerable<DTInterfaceInfo> ifenum =
from entity in dtdlOM.Values
where entity.EntityKind == DTEntityKind.Interface
select entity as DTInterfaceInfo;
interfaces.AddRange(ifenum);
foreach (DTInterfaceInfo dtif in interfaces)
{
PrintInterfaceContent(dtif, dtdlOM);
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Failed due to {ex}");
throw;
}
}
public void PrintInterfaceContent(DTInterfaceInfo dtif, IReadOnlyDictionary<Dtmi, DTEntityInfo> dtdlOM, int indent = 0)
{
var sb = new StringBuilder();
for (int i = 0; i < indent; i++) sb.Append(" ");
Console.WriteLine($"{sb}Interface: {dtif.Id} | {dtif.DisplayName}");
Dictionary<string, DTContentInfo> contents = dtif.Contents;
foreach (DTContentInfo item in contents.Values)
{
switch (item.EntityKind)
{
case DTEntityKind.Property:
DTPropertyInfo pi = item as DTPropertyInfo;
Console.WriteLine($"{sb}--Property: {pi.Name} with schema {pi.Schema}");
break;
case DTEntityKind.Relationship:
DTRelationshipInfo ri = item as DTRelationshipInfo;
Console.WriteLine($"{sb}--Relationship: {ri.Name} with target {ri.Target}");
break;
case DTEntityKind.Telemetry:
DTTelemetryInfo ti = item as DTTelemetryInfo;
Console.WriteLine($"{sb}--Telemetry: {ti.Name} with schema {ti.Schema}");
break;
case DTEntityKind.Component:
DTComponentInfo ci = item as DTComponentInfo;
Console.WriteLine($"{sb}--Component: {ci.Id} | {ci.Name}");
DTInterfaceInfo component = ci.Schema;
PrintInterfaceContent(component, dtdlOM, indent + 1);
break;
}
}
}
}
}
Next steps
Once you're done writing your models, see how to upload them (and do other management operations) with the DigitalTwinsModels APIs:
Maklum balas
Kirim dan lihat maklum balas untuk