-
Notifications
You must be signed in to change notification settings - Fork 8
basic
This topic contains the following examples:
- Loading a Document
- Saving a Document
- Creation of a CAEX document
- Accessing properties using Indexers
- Traversing an Instance Hierarchy
- Copying Elements
- Insertion of Elements
- Removal of Elements
These code examples show basic principles for AutomationML application development using the AMLEngine. The class diagram below only shows the top level classes used in the examples and which are needed to model an automation system topology. The CAEX Classes are all defined in the Aml.Engine.CAEX
namespace.
The CAEXDocument
represents the base class for creating and processing AutomationML documents. There are various loading methods for processing existing documents. The most common is loading a document from a file. Other loading methods exist for byte arrays, streams or strings. Loading a document from a stream is required for processing packed documents of an AutomationMLContainer
.
using Aml.Engine.CAEX;
using Aml.Engine.AmlObjects;
// loading from a file
var document = CAEXDocument.LoadFromFile ("myFile.aml");
// loading from a file with indices for fast queries (use this for read-only documents only)
var document = CAEXDocument.LoadFromFile ("myFile.aml", createIndices:true);
// loading an AutomationML container from a file and the contained root
// AutomationML document from the container stream.
var container = new AutomationMLContainer ("myContainer.amlx");
var rootDocument = CAEXDocument.LoadFromStream ( container.RootDocumentStream());
CAEX documents can be saved as a file, a stream or a string.
using Aml.Engine.CAEX;
myDocument.SaveToFile ("myFile.aml", true);
With the introduction of CAEX version 3.0, CAEX documents can be created in different versions. The standard, without explicit version specification, is the use of CAEX 3.0.
using Aml.Engine.CAEX;
// a version CAEX 3.0 document
var document = CAEXDocument.New_CAEXDocument ();
// appending some content
var myIH = document.CAEXFile.InstanceHierarchy.Append("myIH");
var myIE = myIH.InternalElement.Append("myIE");
// a version 2.15 document
var document2 = CAEXDocument.New_CAEXDocument (CAEXSchema.CAEX2_15);
There are index based access methods to get a specific element in a sequence. The index based access is possible for a CAEXSequence
and a CAEXSequenceOfCAEXObjects
.
- In most sequences of type
CAEXSequenceOfCAEXObjects
, name uniqueness is required. The object name can therefore be used as an index. - For a hierarchy of sequences it is also possible to define an index by using the path (concatenation of names, using the
PathPartSeperator
between each name or simply an enumeration of names. - For a
CAEXSequence
a name-value pair can be defined as an index, the name denotes an attribute of an element and the value denotes the attribute value. These are not CAEX element attributes, butxs-attribute
elements such as the Alias-Attribute of anExternalReferenceType
.
using Aml.Engine.CAEX;
var document = CAEXDocument.New_CAEXDocument ();
// create an empty InstanceHierarchy
var myIH = document.CAEXFile.InstanceHierarchy.Append("myIH");
// Get the first CAEXElement from the sequence of InstanceHierarchies
myIH = document.CAEXFile.InstanceHierarchy[0];
// Get the first CAEXElement from the sequence of InstanceHierarchies with the name "myIH"
myIH = document.CAEXFile.InstanceHierarchy["myIH"];
// Append an InternalElement named "IE1" with one child element "IE1_1"
var ie1_1 = myIH.InternalElement.Append("IE1").Append("IE1_1");
// set the ID
ie_1.ID ="E1";
// Access the child InternalElement from the InstanceHierarchy
// by specifying the names of the element tree
ie1_1 = myIH.InternalElement["IE1", "IE1_1"];
// Access the child InternalElement from the InstanceHierarchy
// by specifying the path to the child
ie1_1 = myIH.InternalElement["IE1/IE1_1"];
// Access the InternalElement using the ID-Attribute
ie1_1 = myIH.InternalElement["IE1"]?.InternalElement[("ID","E1")];
// Append an Attribute named "AT1" with one child attribute "AT1_1"
var at1_1 = ie1_1.Attribute.Append("AT1").Attribute.Append("AT1_1");
// Access the child Attribute from the InternalElement
// by specifying the names of the attribute element tree (this method is CAEX schema independent)
at1_1 = myIE.Attribute["AT1", "AT1_1"];
at1_1 = myIE.Attribute["AT1.AT1_1"]; // this mode is defined for CAEX 2.15 only
at1_1 = myIE.Attribute["AT1/AT1_1"]; // this mode is defined for CAEX 3.0 only
The most common way to process elements is to search the element hierarchy. The direct children of an element can be searched or all descendants of an element or all descendants with certain properties.
using Aml.Engine.CAEX;
var document = CAEXDocument.LoadFromFile("myFile.aml");
// browse the Instance Hierarchies in the file to import some elements
foreach (var instanceHierarchy in document.CAEXFile.InstanceHierarchy)
{
// browse all InternalElements deep and import the internal Elements to your system
foreach (var internalElement in instanceHierarchy.Descendants<InternalElementType>())
{
// ToDo: add code to import the InternalElement
}
}
When CAEX Elements are copied you can decide to automatically assign new IDs to the copied elements. If the copied structure contains ID references, then these references will also get updated. When classes are copied, it is possible to copy the class either with or without all its contained child classes.
using Aml.Engine.CAEX;
void CopyElements(CAEXDocument document)
{
// adding a Class library and some classes organized in a class tree
var systemUnitClassLib = document.CAEXFile.SystemUnitClassLib.Append("Slib");
var suc1 = systemUnitClassLib.SystemUnitClass.Append("s1");
var suc2 = suc1.SystemUnitClass.Append("s2");
var suc3 = suc2.SystemUnitClass.Append("s3");
// adding some elements to the class
suc1.InternalElement.Append("ie1");
// copies the full class tree including the elements
var suc1Tree = suc1.Copy(deepCopy:true, assignNewIDs:true, includeSubClasses:true);
// copies only suc1, omitting the nested classes
var suc1Class = suc1.Copy(deepCopy:true, assignNewIDs:true, includeSubClasses:false);
// copies only suc1, omitting the nested classes and elements
var suc1ClassWithoutElements = suc1.Copy(deepCopy:false, assignNewIDs:true, includeSubClasses:false);
}
The CAEX Class model defines various element sequences where you can insert new elements. You need not to know the appropriate sequence for an element, the AMLEngine always selects the correct sequence on insertion requests. CAEX objects which can be part of a sequence of other objects of the same type are implementations of IMultipleOccurrences
.
using Aml.Engine.CAEX;
void InsertElements(CAEXDocument document)
{
// adding a Class library and a class with element and attribute
var systemUnitClassLib = document.CAEXFile.SystemUnitClassLib.Append("Slib");
var suc1 = systemUnitClassLib.SystemUnitClass.Append("s1");
var element = suc1.InternalElement.Append("element1");
var attribute = suc1.Attribute.Append("attribute1");
// insert an element copy to the class; the element is automatically
// inserted as the last element in the InternalElement collection of the class.
suc1.Insert(element.Copy(), asFirst: false);
// inserts a copy of the element after the element.
element.InsertAfter((InternalElementType)element.Copy());
// inserts a copy of the element at position 1 of the InternalElement collection
// (it becomes the 2nd. element in the collection)
suc1.InternalElement.InsertAt(1, (InternalElementType)element.Copy());
// inserts an attribute copy at the first position; the element is automatically
// inserted in the Attribute collection of the class.
suc1.Insert(attribute.Copy(), asFirst: true);
}
When elements are removed from a document it is possible for specific elements to also remove all remaining references to the element.
using Aml.Engine.CAEX;
void RemoveElements(CAEXDocument document)
{
// adding a Class library and some classes organized in a class tree
var systemUnitClassLib = document.CAEXFile.SystemUnitClassLib.Append("Slib");
var suc1 = systemUnitClassLib.SystemUnitClass.Append("s1");
var suc2 = suc1.SystemUnitClass.Append("s2");
var suc3 = suc2.SystemUnitClass.Append("s3");
var suc4 = suc2.SystemUnitClass.Append("s3");
// suc2 becomes a sub class from suc1
suc2.BaseClass = suc1;
// suc3 becomes a sub class from suc2
suc3.BaseClass = suc2;
// suc4 becomes a sub class from suc3
suc4.BaseClass = suc3;
// this will remove the class suc2 and the base class relation in suc3
suc2.Remove(removeRelations:true);
// this will remove the class suc3 but not the base class relation in suc4
suc3.Remove(removeRelations:false);
}
Home | Installation | API | Solutions
Getting Started
- Install
- First Steps with CAEX
- Working with CAEX Libraries
- Working with CAEX Relations
- Managing Inheritance
- Attribut Values
- Document Versions
Extended Examples
API Reference Guide